8000 [AAP-96820] Put receptor work-unit operations behind an interface with a fake by chrismeyersfsu · Pull Request #16729 · ansible/awx · GitHub
[go: up one dir, main page]

Skip to content

[AAP-96820] Put receptor work-unit operations behind an interface with a fake - #16729

Draft
chrismeyersfsu wants to merge 5 commits into
cmeyers-adoption-seam1-decisionsfrom
cmeyers-adoption-seam2-receptor-work
Draft

chrismeyersfsu wants to merge 5 commits into
cmeyers-adoption-seam1-decisionsfrom
cmeyers-adoption-seam2-receptor-work

Conversation

@chrismeyersfsu
Copy link
Copy Markdown
Member
SUMMARY

Stacked on #16728.

Streaming a job's results, reading a work unit's status, canceling and releasing it now go through a small ReceptorWork class instead of raw receptorctl commands:

Method receptorctl call
list() work list
status(unit_id) work status <unit>
results(unit_id, startpos=None) get_work_results(..., return_socket=True, return_sockfile=True)
cancel(unit_id) work cancel <unit>
release(unit_id) work release <unit>

The process phase, its error handling, work release, same-controller adoption (reattach_to_work_unit) and awx_receptor_workunit_reaper take a ReceptorWork. Submitting work (the transmit phase) still talks to receptorctl directly; adoption never submits. Behavior is unchanged.

awx/main/tests/fake_receptor.py adds:

  • FakeReceptorWork, which serves the same line protocol the ansible-runner worker writes, from canned events, so AWX's real process-phase code parses it. Per unit it can end a stream after N events, fail status calls, or lose the unit.
  • RecordingDispatcher, which stands in for the callback-receiver queue so tests can see which events would be saved.

New functional tests run the real reattach, dedup and finalize code against it:

  • a finished unit is replayed and finalized, and the unit released;
  • events already saved are not dispatched again, including ones saved out of order;
  • a failed playbook finalizes failed;
  • a unit that is still running, or gone, defers adoption;
  • the work-unit reaper releases units of finished jobs only.

One test records today's behavior when a results stream breaks during replay: a unit that succeeded is finalized failed, with only the events read before the break. It documents the current behavior and doesn't change it. Failure testing of #16669 hit this same pattern on a live cluster, where it took a 5–25 minute run to reproduce.

ISSUE TYPE
  • Bug, Docs Fix or other nominal change
COMPONENT NAME
  • Other (receptor job streaming and adoption)
STEPS TO REPRODUCE AND EXTRA INFO
$ py.test awx/main/tests/unit/tasks awx/main/tests/functional/tasks awx/main/tests/functional/test_dispatch.py awx/main/tests/unit/test_tasks.py
457 passed
$ py.test awx/main/tests/unit
1668 passed, 1 error (TestGenericRun::test_generic_failure: "Expected ServiceID to be created"; also fails on devel in this environment)
$ ruff check / ruff format --check
All checks passed!

@coderabbitai
coderabbitai Bot commented Oct 11, 2026 •
Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Comment @coderabbitai help to get the list of available commands.

chrismeyersfsu and others added 2 commits October 12, 2026 13:17
Move the decisions the heartbeat makes about lost instances and orphaned
jobs into awx.main.tasks.adoption_decisions: which peers are lost, which
lost instances the mesh gate lets through, what happens to a lost
instance and its jobs, whether a running job is adopted, reaped or left
alone, and whether an orphan is past the adoption deadline. The
functions read plain attributes and touch no database, receptor or
dispatcher, so they can be tested with simple objects.

awx.main.tasks.system keeps the queries and side effects and calls the
decisions. Behavior is unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
gate_lost_instances now takes the mesh check as a callable and skips it
when nothing is lost, so the heartbeat has no branch of its own there.
New tests cover a lost instance's job the decision doesn't reap, and a
heartbeat job the decision skips.

Co-Authored-By: Claude <noreply@anthropic.com>
chrismeyersfsu and others added 3 commits October 13, 2026 05:05
Cases that differ only in their inputs are now rows of one test, each
named by its id.

Co-Authored-By: Claude <noreply@anthropic.com>
Streaming results, reading status, canceling and releasing a work unit
now go through ReceptorWork instead of raw receptorctl commands. The
process phase, error handling, release, same-controller adoption and the
work-unit reaper take a ReceptorWork. Behavior is unchanged.

awx.main.tests.fake_receptor provides FakeReceptorWork, which serves the
ansible-runner worker line protocol from canned events and can break a
stream partway, fail status calls or lose a unit. New functional tests
drive the real reattach, dedup and finalize code against it, including
one that records today's behavior when a results stream breaks: a unit
that succeeded is finalized failed.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@chrismeyersfsu
chrismeyersfsu force-pushed the cmeyers-adoption-seam2-receptor-work branch from c366502 to 5824cdc Compare October 13, 2026 09:06
@codecov
codecov Bot commented Oct 13, 2026 •
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.35036% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.18%. Comparing base (28b0bc8) to head (5824cdc).
✅ All tests successful. No failed tests found.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0