Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/phpunit-feature.yml
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ jobs:
-w /app \
--entrypoint sh \
durable-workflow-server-corpus-validator \
-lc 'set -eu; tar --no-same-owner -xf - -C /app; cp -a /app/workflow-package /workflow; php scripts/ci/prepare-release-workflow-composer-metadata.php; composer update durable-workflow/workflow --with-dependencies --minimal-changes --no-install --no-scripts --no-autoloader --no-interaction --no-progress --prefer-dist; composer install --no-interaction --no-progress --prefer-dist; git --version; vendor/bin/phpunit --version; git rev-parse --verify "$CORPUS_BASE_REF^{commit}"; php scripts/ci/check-worker-openapi-evolution.php "$CORPUS_BASE_REF"; vendor/bin/phpunit tests/Feature tests/Unit/NexusContractTest.php tests/Unit/CodecRegressionCorpusTest.php tests/Unit/PhpunitFeatureWorkflowContractTest.php tests/Unit/OpenApiDocumentEvolutionTest.php tests/Unit/NamespaceConformanceRunnerContractTest.php tests/Unit/NamespaceRuntimeContractTest.php tests/Unit/SchedulesConformanceRunnerContractTest.php tests/Unit/SchedulesRuntimeContractTest.php tests/Unit/ServerParitySdkDirectionResponseSummaryTest.php tests/Unit/ServerParitySdkQueryTransportTest.php tests/Unit/ServerParitySdkUpdateTransportTest.php tests/Unit/ServerParityLockPressureRetryTest.php --no-progress --colors=never; vendor/bin/phpunit tests/Unit/ReleaseImageImmutabilityGuardTest.php --no-progress --colors=never; vendor/bin/phpunit tests/Unit/ReleaseImagePublishWorkflowContractTest.php --filter test_php_security_audits_fail_before_release_publication --no-progress --colors=never; python3 scripts/ci/validate-regression-corpus.py --base-ref "$CORPUS_BASE_REF" --verify-counterfactual'
-lc 'set -eu; tar --no-same-owner -xf - -C /app; cp -a /app/workflow-package /workflow; php scripts/ci/prepare-release-workflow-composer-metadata.php; composer update durable-workflow/workflow --with-dependencies --minimal-changes --no-install --no-scripts --no-autoloader --no-interaction --no-progress --prefer-dist; composer install --no-interaction --no-progress --prefer-dist; git --version; vendor/bin/phpunit --version; git rev-parse --verify "$CORPUS_BASE_REF^{commit}"; php scripts/ci/check-worker-openapi-evolution.php "$CORPUS_BASE_REF"; vendor/bin/phpunit tests/Feature tests/Unit/NexusContractTest.php tests/Unit/CodecRegressionCorpusTest.php tests/Unit/PhpunitFeatureWorkflowContractTest.php tests/Unit/OpenApiDocumentEvolutionTest.php tests/Unit/NamespaceConformanceRunnerContractTest.php tests/Unit/NamespaceRuntimeContractTest.php tests/Unit/SchedulesConformanceRunnerContractTest.php tests/Unit/SchedulesRuntimeContractTest.php tests/Unit/ServerParitySdkDirectionResponseSummaryTest.php tests/Unit/ServerParitySdkQueryTransportTest.php tests/Unit/ServerParitySdkUpdateTransportTest.php tests/Unit/ServerParityLockPressureRetryTest.php tests/Unit/ServerParityManyUpdatesRetryTest.php --no-progress --colors=never; vendor/bin/phpunit tests/Unit/ReleaseImageImmutabilityGuardTest.php --no-progress --colors=never; vendor/bin/phpunit tests/Unit/ReleaseImagePublishWorkflowContractTest.php --filter test_php_security_audits_fail_before_release_publication --no-progress --colors=never; python3 scripts/ci/validate-regression-corpus.py --base-ref "$CORPUS_BASE_REF" --verify-counterfactual'

- name: Select production image qualification for changed build inputs
id: image_inputs
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/server-parity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ on:
- tests/Fixtures/ServerParityNormalization/**
- tests/Unit/ServerParityRunnerTest.mjs
- tests/Unit/ServerParityRunnerBlockedExcerptTest.mjs
- tests/Unit/ServerParityProbeNotesTest.mjs
- tests/Unit/ServerParitySdkDirectionLanesTest.mjs
- tests/Unit/ServerParityCodecDeadlineCellsTest.mjs
- tests/Unit/ServerParityArtifactSummaryTest.mjs
Expand Down Expand Up @@ -61,6 +62,7 @@ on:
- tests/Unit/ServerParityConcurrentWaitsContractTest.mjs
- tests/Unit/ServerParityContinueTransfersContractTest.mjs
- tests/Unit/ServerParityLargeCommandBatchesContractTest.mjs
- tests/Unit/ServerParityManyUpdatesContractTest.mjs
- tests/Unit/ServerParityStartSearchAttributesContractTest.mjs
- tests/Unit/ServerParityQueryArgumentsContractTest.mjs
- tests/Unit/ServerParityQueryContractArgumentsContractTest.mjs
Expand Down Expand Up @@ -1987,7 +1989,7 @@ jobs:
bash scripts/ci/run-composer.sh --rm -v "$PWD:/source" -w /source -- \
install --working-dir=scripts/conformance/server-parity --no-interaction --no-progress
docker run --rm --user=1000:1000 --entrypoint node -v "$PWD:/source:ro" -w /source \
"$image" --test tests/Unit/ServerParityRunnerTest.mjs tests/Unit/ServerParityRunnerBlockedExcerptTest.mjs tests/Unit/ServerParitySdkDirectionLanesTest.mjs tests/Unit/ServerParityCodecDeadlineCellsTest.mjs tests/Unit/ServerParityCooperativeContractTest.mjs tests/Unit/ServerParityChildCancellationContractTest.mjs tests/Unit/ServerParityScheduleContractTest.mjs tests/Unit/ServerParityVisibilityContractTest.mjs tests/Unit/ServerParityAdmissionContractTest.mjs tests/Unit/ServerParityRoleTokenContractTest.mjs tests/Unit/ServerParityWorkerDeregistrationContractTest.mjs tests/Unit/ServerParitySearchAttributeContractTest.mjs tests/Unit/ServerParityWorkerListingContractTest.mjs tests/Unit/ServerParityWorkerReplacementContractTest.mjs tests/Unit/ServerParityPatchDeploymentContractTest.mjs tests/Unit/ServerParityWaitingHistoryContractTest.mjs tests/Unit/ServerParityTaskRetryContractTest.mjs tests/Unit/ServerParityPublishedPatchContractTest.mjs tests/Unit/ServerParityPublishedPatchTransportTest.mjs tests/Unit/ServerParityRecordFileTest.mjs tests/Unit/ServerParityFailureLocationTest.mjs tests/Unit/ServerParityFailureExcerptTest.mjs tests/Unit/ServerParityLateWorkflowCompletionContractTest.mjs tests/Unit/ServerParityStorageTestContractTest.mjs tests/Unit/ServerParitySchedulePoliciesContractTest.mjs tests/Unit/ServerParitySignalsBeforeWorkerContractTest.mjs tests/Unit/ServerParityScheduleCatalogContractTest.mjs tests/Unit/ServerParityOperatorMetricsContractTest.mjs tests/Unit/ServerParityActivityLeaseRenewalContractTest.mjs tests/Unit/ServerParityConcurrentWaitsContractTest.mjs tests/Unit/ServerParityContinueTransfersContractTest.mjs tests/Unit/ServerParityLargeCommandBatchesContractTest.mjs tests/Unit/ServerParityStartSearchAttributesContractTest.mjs tests/Unit/ServerParityQueryArgumentsContractTest.mjs tests/Unit/ServerParityQueryContractArgumentsContractTest.mjs tests/Unit/ServerParityParentCloseCancellationContractTest.mjs tests/Unit/ServerParityRecordLocalActivityContractTest.mjs tests/Unit/ServerParityActivityCancellationAckContractTest.mjs tests/Unit/ServerParityServiceCatalogContractTest.mjs tests/Unit/ServerParityServiceEndpointsContractTest.mjs tests/Unit/ServerParityServiceCallsContractTest.mjs tests/Unit/ServerParityWorkflowImportContractTest.mjs tests/Unit/ServerParityWaterlineImportContractTest.mjs tests/Unit/ServerParitySystemMetricsContractTest.mjs tests/Unit/ServerParityOperatorDashboardTypesContractTest.mjs tests/Unit/ServerParityPrometheusMetricsContractTest.mjs tests/Unit/ServerParityPayloadCleanupContractTest.mjs tests/Unit/ServerParityRepairPassContractTest.mjs tests/Unit/ServerParityClusterInfoContractTest.mjs tests/Unit/ServerParityNamespaceDeleteContractTest.mjs tests/Unit/ServerParityMessageStreamsContractTest.mjs tests/Unit/ServerParityCancellationScopesContractTest.mjs tests/Unit/ServerParityWorkflowPollRequestContractTest.mjs tests/Unit/ServerParityUpdateValidationContractTest.mjs tests/Unit/ServerParityFixtureSelectionTest.mjs tests/Unit/ServerParityUpdateValidationRetryTest.mjs tests/Unit/ServerParityKilledAuthorPollTest.mjs tests/Unit/ServerParityImagePullTest.mjs tests/Unit/ServerParityAdapterCacheTest.mjs tests/Unit/ServerParityWorkerSessionsContractTest.mjs tests/Unit/ServerParityWorkerSessionActivitiesContractTest.mjs tests/Unit/ServerParityNexusOperationsContractTest.mjs tests/Unit/ServerParityBridgeAdaptersContractTest.mjs tests/Unit/ServerParityWorkflowStreamWritesContractTest.mjs > parity-evidence/comparator-tests.txt
"$image" --test tests/Unit/ServerParityRunnerTest.mjs tests/Unit/ServerParityRunnerBlockedExcerptTest.mjs tests/Unit/ServerParityProbeNotesTest.mjs tests/Unit/ServerParitySdkDirectionLanesTest.mjs tests/Unit/ServerParityCodecDeadlineCellsTest.mjs tests/Unit/ServerParityCooperativeContractTest.mjs tests/Unit/ServerParityChildCancellationContractTest.mjs tests/Unit/ServerParityScheduleContractTest.mjs tests/Unit/ServerParityVisibilityContractTest.mjs tests/Unit/ServerParityAdmissionContractTest.mjs tests/Unit/ServerParityRoleTokenContractTest.mjs tests/Unit/ServerParityWorkerDeregistrationContractTest.mjs tests/Unit/ServerParitySearchAttributeContractTest.mjs tests/Unit/ServerParityWorkerListingContractTest.mjs tests/Unit/ServerParityWorkerReplacementContractTest.mjs tests/Unit/ServerParityPatchDeploymentContractTest.mjs tests/Unit/ServerParityWaitingHistoryContractTest.mjs tests/Unit/ServerParityTaskRetryContractTest.mjs tests/Unit/ServerParityPublishedPatchContractTest.mjs tests/Unit/ServerParityPublishedPatchTransportTest.mjs tests/Unit/ServerParityRecordFileTest.mjs tests/Unit/ServerParityFailureLocationTest.mjs tests/Unit/ServerParityFailureExcerptTest.mjs tests/Unit/ServerParityLateWorkflowCompletionContractTest.mjs tests/Unit/ServerParityStorageTestContractTest.mjs tests/Unit/ServerParitySchedulePoliciesContractTest.mjs tests/Unit/ServerParitySignalsBeforeWorkerContractTest.mjs tests/Unit/ServerParityScheduleCatalogContractTest.mjs tests/Unit/ServerParityOperatorMetricsContractTest.mjs tests/Unit/ServerParityActivityLeaseRenewalContractTest.mjs tests/Unit/ServerParityConcurrentWaitsContractTest.mjs tests/Unit/ServerParityContinueTransfersContractTest.mjs tests/Unit/ServerParityLargeCommandBatchesContractTest.mjs tests/Unit/ServerParityManyUpdatesContractTest.mjs tests/Unit/ServerParityStartSearchAttributesContractTest.mjs tests/Unit/ServerParityQueryArgumentsContractTest.mjs tests/Unit/ServerParityQueryContractArgumentsContractTest.mjs tests/Unit/ServerParityParentCloseCancellationContractTest.mjs tests/Unit/ServerParityRecordLocalActivityContractTest.mjs tests/Unit/ServerParityActivityCancellationAckContractTest.mjs tests/Unit/ServerParityServiceCatalogContractTest.mjs tests/Unit/ServerParityServiceEndpointsContractTest.mjs tests/Unit/ServerParityServiceCallsContractTest.mjs tests/Unit/ServerParityWorkflowImportContractTest.mjs tests/Unit/ServerParityWaterlineImportContractTest.mjs tests/Unit/ServerParitySystemMetricsContractTest.mjs tests/Unit/ServerParityOperatorDashboardTypesContractTest.mjs tests/Unit/ServerParityPrometheusMetricsContractTest.mjs tests/Unit/ServerParityPayloadCleanupContractTest.mjs tests/Unit/ServerParityRepairPassContractTest.mjs tests/Unit/ServerParityClusterInfoContractTest.mjs tests/Unit/ServerParityNamespaceDeleteContractTest.mjs tests/Unit/ServerParityMessageStreamsContractTest.mjs tests/Unit/ServerParityCancellationScopesContractTest.mjs tests/Unit/ServerParityWorkflowPollRequestContractTest.mjs tests/Unit/ServerParityUpdateValidationContractTest.mjs tests/Unit/ServerParityFixtureSelectionTest.mjs tests/Unit/ServerParityUpdateValidationRetryTest.mjs tests/Unit/ServerParityKilledAuthorPollTest.mjs tests/Unit/ServerParityImagePullTest.mjs tests/Unit/ServerParityAdapterCacheTest.mjs tests/Unit/ServerParityWorkerSessionsContractTest.mjs tests/Unit/ServerParityWorkerSessionActivitiesContractTest.mjs tests/Unit/ServerParityNexusOperationsContractTest.mjs tests/Unit/ServerParityBridgeAdaptersContractTest.mjs tests/Unit/ServerParityWorkflowStreamWritesContractTest.mjs > parity-evidence/comparator-tests.txt
docker run --rm --user=1000:1000 --cpus=1 --memory=256m --memory-swap=256m \
--network=none --entrypoint node -v "$PWD:/source:ro" -w /source \
"$image" --test tests/Unit/ServerParityCodecDeadlineLoadTest.mjs > parity-evidence/codec-load-tests.txt
Expand Down
34 changes: 34 additions & 0 deletions docs/rust-server-port-checkpoints/2026-10-29-many-updates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# October 29, descriptions after more than 64 updates

- **Before.** The October 23 change removed native's 64-update admission
cap ([update lifetime cap](2026-10-23-update-lifetime-cap.md)). The
update summary that describes a run's waits still stopped at 64 updates
(`update_summary.rs`): it read every update wait over the run's life,
`LIMIT 65`, and gave up past 64. A run that had taken 65 updates was
described with no wait (`wait_kind` null), though its signal wait was
still open.
- **Contract** (published 2.11.5; `WorkflowController::show`, Workflow 2.15.1
`RunWaitView`, `StructuralLimits::pendingUpdateCountLimit`):
- only pending updates are bounded (500 by default);
- a run is described by its open waits, however many updates it has
taken;
- an accepted update that is still open is the run's wait
("Waiting for update set").
- **Fixture.** `many-updates`, raw worker HTTP on protocol 1.20 in a fresh
namespace. A run opens a signal wait and takes 65 updates. Each is
accepted (202), delivered on its own workflow task and completed (200,
run waiting). The probe records:
- the description before and after the updates (`signal`);
- with a 66th update left accepted (`update`);
- the history counts (66 `UpdateAccepted`, 65 `UpdateCompleted`).

The worker heartbeats every 20 seconds, since the loop outlasts the
worker staleness window. The run is terminated after recording, so its
never-polled update task does not stay for later fixtures. The probe declares a 180-second budget; locally it took
about 80 seconds against published PHP.
- **Native.** The summary keeps every accepted update and reads every
update wait. Only one open update at a time is described, as before.
- **Not covered here.** The child summary still stops at 100 children
over a run's life (`child_summary.rs`); that needs its own fixture.
- **Tests.** `many_updates.rs` fails on the previous source (`wait_kind`
null after 65 updates) and passes now.
13 changes: 10 additions & 3 deletions docs/rust-server-port.md
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,16 @@ contract fixture before its correction.
150 timers, 150 activities, a 150-member group and a 1,001-member group
against published 2.11.5
([checkpoint](rust-server-port-checkpoints/2026-10-29-large-command-batches.md)).
- **Descriptions after more than 64 updates** (October 29, closed).
Published PHP bounds only pending updates, not how many a run takes over
its life. The October 23 change removed native's 64-update admission cap,
but its update summary still gave up past 64 updates. A run that had
taken 65 was described with no wait. The bound is removed. The
`many-updates` fixture records a run waiting for a signal through 65
completed updates, then a 66th left accepted, against published 2.11.5
([checkpoint](rust-server-port-checkpoints/2026-10-29-many-updates.md)).
The child summary still stops at 100 children over a run's life; that
needs its own fixture.
- **Trace context (Core 2.10, published in Server 2.11.1).** Core adds
nullable `observability_context` columns on runs, commands and tasks.
Native has no carrier: it accepts and ignores a top-level carrier on
Expand Down Expand Up @@ -667,9 +677,6 @@ contract fixture before its correction.
`none` driver or database runtime credentials, which published PHP does
not. Without a tenant-bound administrator, native does not read a namespace
route's target from a JSON body `name`.
- **Described command previews.** Published PHP's run description gives
each command `payload_preview_omitted` and, for a cancel or terminate, its
decoded `reason`. Native's described commands carry neither.
- **Command route names.** Published PHP records each request's route name in
its command context, and its unnamed workflow routes get a name generated
per deployment. Native records names only for the named schedule routes.
Expand Down
9 changes: 5 additions & 4 deletions rust/src/runtime/update_summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ impl UpdateSummaryHistory {
return false;
}
if kind == "UpdateAccepted" {
if self.updates.len() >= 64
|| self.updates.contains_key(id)
// Published PHP bounds only pending updates, not how many a
// run takes over its life, so every accepted update is kept.
if self.updates.contains_key(id)
// A run continued from a predecessor takes its pending update
// without an ordering state, ready for delivery.
|| payload.get("ordering_state").is_some_and(|state| state != "ready")
Expand Down Expand Up @@ -132,9 +133,9 @@ where
history: &UpdateSummaryHistory,
summary: &mut ActiveSummary,
) -> Result<bool> {
let rows = Self::query("SELECT w.*,u.id AS update_id,u.workflow_command_id,u.workflow_instance_id AS update_instance,u.update_name,u.status AS update_status,u.command_sequence AS update_command_sequence,u.workflow_sequence,c.id AS matched_command_id,c.command_sequence AS matched_command_sequence FROM workflow_run_waits w LEFT JOIN workflow_updates u ON u.id=w.resume_source_id AND u.workflow_run_id=w.workflow_run_id LEFT JOIN workflow_commands c ON c.id=u.workflow_command_id AND c.workflow_run_id=w.workflow_run_id WHERE w.workflow_run_id=$1 AND w.kind='update' ORDER BY w.command_sequence,w.wait_id LIMIT 65")
let rows = Self::query("SELECT w.*,u.id AS update_id,u.workflow_command_id,u.workflow_instance_id AS update_instance,u.update_name,u.status AS update_status,u.command_sequence AS update_command_sequence,u.workflow_sequence,c.id AS matched_command_id,c.command_sequence AS matched_command_sequence FROM workflow_run_waits w LEFT JOIN workflow_updates u ON u.id=w.resume_source_id AND u.workflow_run_id=w.workflow_run_id LEFT JOIN workflow_commands c ON c.id=u.workflow_command_id AND c.workflow_run_id=w.workflow_run_id WHERE w.workflow_run_id=$1 AND w.kind='update' ORDER BY w.command_sequence,w.wait_id")
.bind(run).fetch_all(&mut **tx).await?;
if rows.len() != history.updates.len() || rows.len() > 64 {
if rows.len() != history.updates.len() {
return Ok(false);
}
let mut open = None;
Expand Down
2 changes: 2 additions & 0 deletions rust/tests/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ mod workflow_import_fences;

#[path = "execution/large_command_batches.rs"]
mod large_command_batches;
#[path = "execution/many_updates.rs"]
mod many_updates;

#[path = "execution/query_argument_routing.rs"]
mod query_argument_routing;
Expand Down
Loading
Loading