Skip to content

Route pinned runs by their recorded definition like PHP; run every fixture check before failing - #667

Merged
rmcdaniel merged 8 commits into
mainfrom
rust-325-definition-routing
Oct 23, 2026
Merged

rmcdaniel merged 8 commits into
mainfrom
rust-325-definition-routing

Conversation

@rmcdaniel

Copy link
Copy Markdown
Member

Part of #325. Two commits.

1. Workflow definition routing like Server 2.10.0

Native records the definition fingerprint a start's worker cohort agrees on, as PHP does. It then offered that run's workflow tasks to any worker. PHP routes them by the recorded definition (WorkflowDefinitionRouting, WorkflowReplayEligibility). Native now does too:

  • Claim (forWorker). For a worker-pinned run:

    • a worker advertising the recorded fingerprint takes the task;
    • a worker with another definition waits while an eligible peer has the recorded one. After that it takes the task only if it advertises workflow_entry_arguments_validation;
    • workers without a fingerprint, and runs without a recorded one, get nothing.

    Eligible peers are fresh workers on the run's queue and build that support the type and can replay its cooperative-cancellation and metadata history. An unpinned run goes to any worker.

  • Protocol version. Registrations and heartbeats record it under _worker_protocol_version in the process metrics, as PHP 2.10.0 does. Worker listings show it.

  • Reports (inspect, forQueue).

    • Describe, repair and debug report definition_routing, with PHP's status, counts, example workers, blocked, runnable_task and resolution.
    • A blocked route is a debug warning (workflow_definition_routing_blocked, needs_attention).
    • Task queue describe samples ready runs and marks the queue's repair as needing attention when one is blocked.

The gap-list entry is removed. Checkpoint: docs/rust-server-port-checkpoints/2026-10-22-definition-routing.md.

2. Fixture steps run every check

The SQLite, PostgreSQL and MySQL fixture steps stopped as soon as native's record of the frozen corpus failed. That skipped every later check in the step: the SDK direction, patch, marker, range and restart profiles.

Since #663, the record names every difference, and there is one: the expected signals-before-worker (cloud discussion 418). That one difference hid all the later checks. The native record and the comparison now keep their status, the rest of each step runs, and the step fails at its end if either failed. Expectations and frozen artifacts are unchanged.

Tests

  • New definition_routing.rs: routing to the recorded definition, entry-validating replacements, unpinned runs, protocol metrics, and the four reports. The worker listing test now expects the protocol key.
  • Full SQLite suite: 398 passed.
  • Routing, worker, poll, child, cooperative, debug, task queue, repair and describe tests: PostgreSQL 134, MySQL 134.

This PR will be merged by hand once all checks, including the Rust suites, pass.

Server 2.10.0's WorkflowDefinitionRouting decides at claim which worker may
take a workflow task of a run whose start recorded its worker cohort's
definition fingerprint. Native offered such tasks to any worker.

Now a worker advertising the recorded fingerprint takes the task. A worker
with another definition waits while an eligible peer has the recorded one,
then takes it only if it advertises workflow_entry_arguments_validation.
Workers without a fingerprint, or runs without a recorded one, get nothing.
Eligible peers follow WorkflowReplayEligibility: fresh, on the run's queue
and build, supporting the type, and able to replay its cooperative
cancellation and metadata history.

Registrations and heartbeats now record their protocol version under
_worker_protocol_version in the process metrics, as PHP 2.10.0 does; worker
listings show it.
Server 2.10.0 reports WorkflowDefinitionRouting's decision for a run's next
due ready workflow task as definition_routing in describe, repair and debug
(inspect), and samples a queue's ready runs in task queue describe
(forQueue). Native now does the same: the recorded context, PHP's status,
eligible worker counts by definition, up to ten example workers, blocked,
runnable_task and PHP's resolution text. A blocked route is a debug warning
(workflow_definition_routing_blocked, diagnostic_status needs_attention) and
marks the queue's repair as needing attention.
The SQLite, PostgreSQL and MySQL fixture steps stopped as soon as native's
record of the frozen corpus failed, which skipped every later check in the
step: the SDK direction, patch, marker, range and restart profiles. One
expected difference (native's Server 2.10.0 SignalRejected in
signals-before-worker) therefore hid everything after it.

The native record and the comparison now keep their status, the rest of
the step runs, and the step fails at its end if either failed. Nothing
about the expectations or the frozen artifacts changes.
The worker-fencing contract compares whole run reads across a live
registration replacement. Native and Server 2.10.0 describe a run with
definition_routing, which reports how the next ready workflow task would
route now; releasing the lease makes that task runnable without changing
the run or its history. The preservation checks now compare the reads
without that block, and a unit case covers both a routing-only change and
a real run change.
The SDK query contract compares the run read before and after a query. definition_routing reports how the next ready task would route now, so a worker leaving changes its counts without touching the run or its history.
@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel

Copy link
Copy Markdown
Member Author

Riding merge train #675 with #667, #669, #670 and #674 on main 17dc12cd, so they share one CI run. This PR closes with a link once the train merges.

@rmcdaniel
rmcdaniel merged commit 437f60d into main Oct 23, 2026
21 of 27 checks passed
@rmcdaniel
rmcdaniel deleted the rust-325-definition-routing branch October 23, 2026 13:31
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.

1 participant