Skip to content

Terminate a workflow natively, as published PHP does - #543

Merged
rmcdaniel merged 17 commits into
mainfrom
rust-325-terminate
Oct 20, 2026
Merged

rmcdaniel merged 17 commits into
mainfrom
rust-325-terminate

Conversation

@rmcdaniel

Copy link
Copy Markdown
Member

Part of #325: API parity. Native now serves POST /api/workflows/{id}/terminate and POST /api/workflows/{id}/runs/{run}/terminate.

Published Workflow runs cancel and terminate through one implementation (attemptTerminalCommand), so native does the same. Terminate records:

  • its own command type, TerminateRequested and WorkflowTerminated;
  • the terminated status, closed reason, failure category and propagation kind;
  • WorkflowTerminatedException.

It closes open tasks, activities and timers exactly as cancel does. A late activity outcome is refused with run_terminated. The response carries the terminate control-plane contract, which matches cancel's.

Terminating a child run is refused with 422 termination_propagation_not_available, and nothing changes. The parent-side ChildRunTerminated projections need their own fixture first; the port log lists this gap.

Fixtures

  • The immediate cancellation fixtures take a command; it defaults to cancel.
  • terminate-before-claim, terminate-pending-timer and terminate-leased-activity reuse the cancellation workflows.
  • The shared contract and its runner unit tests check the termination identity in place of cancellation's.

Checks

  • A local copy of the SQLite parity step recorded published PHP 2.5.14, embedded PHP and native. All six cancel and terminate fixtures passed on every target, and the comparison passed.
  • Native integration tests for both commands pass on SQLite, PostgreSQL and MySQL. The SQLite library and execution suites pass.

The worker listing PR stacks on this branch, so its parity run qualifies both. This branch's own parity run is cancelled as a duplicate.

🤖 Generated with Claude Code

durable-workflow-ops and others added 11 commits October 20, 2026 14:28
Published Workflow runs cancel and terminate through one terminal-command
implementation. Native now does the same: terminate records its own
command, events, status, failure and exception identity, and closes open
work exactly as cancel does. Terminating a child run is refused until the
parent's ChildRunTerminated projections have a fixture.

The shared immediate-cancellation fixtures take a command, and three
terminate fixtures reuse the cancellation workflows.

Part of #325.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Native serves GET /api/workers and GET /api/workers/{id} with PHP's
summary, filters, stale window and refusals. Registration and heartbeat
now keep the facts PHP reports: capacities, bounded task slots, process
metrics, heartbeat cadence and workflow definition fingerprints.
Re-registering with a changed or omitted fingerprint is refused, as PHP
refuses it.

A worker-listing fixture drives this through the unchanged published SDK.

Part of #325.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…5-worker-listing

# Conflicts:
#	docs/rust-server-port.md
A new process registering a worker_id that holds activity leases now
closes its running attempts as expired and returns the tasks to ready,
so the next claim is attempt 2 of the same task. Native used to leave the
task leased for the whole five-minute activity lease. The expired
attempt's late completion gets PHP's whole stale receipt.

A worker-replacement-activity-lease fixture checks this through the
unchanged published SDK.

Part of #325.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rmcdaniel

Copy link
Copy Markdown
Member Author

Cancelled this branch's parity run 39454777693: #544 stacks on this branch, and its parity run 39454805674 qualifies both.

durable-workflow-ops and others added 5 commits October 20, 2026 16:10
@rmcdaniel
rmcdaniel enabled auto-merge October 20, 2026 22:16
@rmcdaniel

Copy link
Copy Markdown
Member Author

Merged main (49a56f5c0, which adds #551 namespace update, #545 database TLS and #556 certifi) into this branch as e7b8dfbed. The only conflict was in the port-log checkpoint list, and I kept both entries.

Parity. I cancelled the Shared Server fixtures run for the merged head (39506903121) as a duplicate:

  • the branch's own change is unchanged since 39484509609, which passed all 13 jobs on 2d6b1e99d;
  • main's additions run their own parity after each merge;
  • runners are congested.

Local check of the merged head. On SQLite, the native lib suite (122) and the execution suite (291) pass.

Auto-merge is on for the required checks.

@rmcdaniel

Copy link
Copy Markdown
Member Author

09d249ca7 merges main again (f4937bed6, #549 multi-node harness). That change touches no native code, parity script or parity workflow, so I cancelled the duplicate Shared Server fixtures run 39508690780. The qualification remains 39484509609.

@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel
rmcdaniel merged commit adefcf8 into main Oct 20, 2026
9 of 14 checks passed
@rmcdaniel
rmcdaniel deleted the rust-325-terminate branch October 20, 2026 22:48
@rmcdaniel

Copy link
Copy Markdown
Member Author

The opt-in native packaging proposal in comments 6301678221 and 6301964569 is accepted for source preparation: build the locked native executable for both architectures inside the existing image, retain PHP as the published default, and require both the explicit engine selection and existing native experimental guard. Preserve current immutable-image identity checks and PHP startup/management behavior. Unknown engine values must refuse clearly; native selection must not run PHP migration or config-cache commands against native storage.

Qualify the actual two architecture images, engine/command selection, database ownership refusals and shutdown before any native packaging claim. This approval is not native runtime or migration acceptance.

For the immediate main promotion order, please acknowledge #552 as the next merge/tag handoff. Its preceding combined head passed the full PHP suite, but main changed again through #543 before protected merge; this is the third ancestry cycle for unchanged PHP. The maintainer is integrating adefcf8 and running fresh normal gates. Finish that qualified merge and immutable PHP 2.9.11 tag before the next native main promotion. Independent native branches, review and admitted qualification continue during this short release handoff. Please acknowledge this order on #552 or #325 so both maintainers have the same decision.

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