Skip to content

Add: Worker.submit with per-run completion handles - #1460

Merged
ChaoWao merged 1 commit into
hw-native-sys:mainfrom
Crane-Liu:codex/worker-async-pr2-run-handle
Jul 25, 2026
Merged

Add: Worker.submit with per-run completion handles#1460
ChaoWao merged 1 commit into
hw-native-sys:mainfrom
Crane-Liu:codex/worker-async-pr2-run-handle

Conversation

@Crane-Liu

@Crane-Liu Crane-Liu commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add Worker.submit(...) -> RunHandle; graph construction stays synchronous, but L3 device work may still be active when submit() returns
  • keep Worker.run(...) source-compatible as submit(...).wait(), still blocking and still returning None
  • RunHandle exposes done, wait(timeout) and result(timeout); the terminal result is cached so repeated and concurrent waits observe the same outcome
  • exactly one waiter performs fence-owned cleanup and _release_run; the others replay the cached result
  • bind wait_run_for, a timed native fence wait that releases the GIL
  • retain the callback, args and config on the handle until the fence fires, so run-owned resources outlive submit()
  • close() fences admission and drains accepted handles before tearing down the worker tree
  • L2 submission stays blocking and returns an already-completed handle

Graph-construction errors remain synchronous in submit(). Device and endpoint
errors are owned by the originating handle, surface from wait()/result(),
and do not poison a later submission.

Scope

Only one live device run is admitted: a later submission drains the previous
handle before building another DAG. This deliberately does not add
prepared-run FIFO admission, a Python dispatcher thread, cancellation, or any
device overlap — preparation of run N+1 still does not overlap execution of
run N.

Series context

Part of the worker async-preparation series; follows #1459, which introduced
per-run identity, the completion fence and per-run error isolation. Prepared-run
admission, K=2 resources and device overlap come later.

Rebase

#1459 has landed, so this branch is rebased onto merged main and the
superseded run-fence commit is dropped. The diff is now this PR's own increment
only: 9 files, +582/-76.

The worker.py conflict against the final #1459 implementation was resolved by
keeping this PR's _submit_l3_locked restructure (submission no longer waits;
cleanup moved into RunHandle) and re-applying #1459's failure-message
plumbing, so a graph-construction failure still reaches the run fence:
_fail_run_submission(run_id, _format_exc("orchestration", e)).

Validation

Re-run after the rebase onto merged main:

  • changed-file pre-commit hooks: passed
  • C++ unit tests: 60/60 passed (ctest --test-dir tests/ut/cpp/build -LE requires_hardware)
  • Python unit tests: 821 passed, 2 skipped (pytest tests/ut)

The architecture-probe and hardware runs quoted before the rebase were against
8e56fa6a and have not been re-run against the current head. GitHub CI is the
automated regression stage.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@ChaoWao, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 19 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 89b089f9-0cdf-4574-b4a9-99625631250a

📥 Commits

Reviewing files that changed from the base of the PR and between 4f62e0c and faf7963.

📒 Files selected for processing (9)
  • docs/orchestrator.md
  • python/bindings/worker_bind.h
  • python/simpler/orchestrator.py
  • python/simpler/worker.py
  • src/common/hierarchical/orchestrator.cpp
  • src/common/hierarchical/orchestrator.h
  • tests/ut/cpp/hierarchical/test_orchestrator.cpp
  • tests/ut/py/test_worker/test_host_worker.py
  • tests/ut/py/test_worker/test_startup_readiness.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@Crane-Liu

Copy link
Copy Markdown
Contributor Author

st-onboard-a2a3 needs a maintainer rerun. The failure is isolated to the
standalone dep_gen smoke: tasks[] omitted task id 0 while all expected
dependency edges were present. The same test_dep_gen.py passed earlier in
this exact CI job as part of the full a2a3 scene suite.

I reran the smoke command on queued a2a3 hardware against this PR's exact
commit. It passed:

  • task: task_20260724_032702_351647729229
  • result: 1 passed, exit 0
  • command scope: test_dep_gen.py --platform a2a3 -p no:xdist --require-pto-isa --enable-dep-gen

The job rerun REST API returns 403 for the fork author's token, so I cannot
rerun it directly. No product-code change was made for this non-reproducible
capture failure.

@Crane-Liu
Crane-Liu force-pushed the codex/worker-async-pr2-run-handle branch from 6e215d8 to 8e56fa6 Compare July 24, 2026 23:59
@ChaoWao
ChaoWao force-pushed the codex/worker-async-pr2-run-handle branch from 8e56fa6 to 5999cb4 Compare July 25, 2026 07:21
@ChaoWao ChaoWao changed the title Feat: add asynchronous Worker run handles (2/7) Add: Worker.submit with per-run completion handles Jul 25, 2026
ChaoWao
ChaoWao previously approved these changes Jul 25, 2026
@ChaoWao
ChaoWao force-pushed the codex/worker-async-pr2-run-handle branch from 5999cb4 to faf7963 Compare July 25, 2026 08:56
Worker.submit() constructs the DAG synchronously and returns a RunHandle
that owns the run's completion, so L3 device work may still be active
after submit() returns. Worker.run() is submit(...).wait(), so existing
callers keep their blocking semantics and None return.

- RunHandle exposes done, wait(timeout) and result(timeout); the terminal
  result is cached, so repeated and concurrent waits observe the same
  outcome and exactly one waiter performs fence-owned cleanup and
  release_run
- wait_run_for binds a timed native fence wait that releases the GIL
- the handle retains the callback, args and config until the fence fires,
  so run-owned resources outlive submit()
- done reports false while a concurrent waiter is publishing cleanup, so
  it never queries a run id that waiter is about to release
- graph-construction errors stay synchronous in submit(); device and
  endpoint errors belong to the originating handle and do not poison a
  later submission
- fail_run_submission closes a run out from whatever state submission
  reached instead of rejecting one that is no longer building: the
  submission failure path waits on that fence, so refusing it left the
  waiter blocked forever
- close() fences admission and drains accepted handles before tearing
  down the worker tree
- L2 submission stays blocking and returns an already-completed handle

Only one live device run is admitted: a later submission drains the
previous handle before building another DAG, so preparation of one run
does not overlap execution of another.
@ChaoWao
ChaoWao merged commit f8e2067 into hw-native-sys:main Jul 25, 2026
14 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants