From 6830350cf36498aee1a7a71a4114b2afa81cfac5 Mon Sep 17 00:00:00 2001 From: Durable Workflow Date: Wed, 21 Oct 2026 08:29:11 +0000 Subject: [PATCH 1/3] Keep the takeover refusal qualifications refusing after cron support #570 made native run cron schedules, so the PostgreSQL and MySQL qualifications' cron schedule no longer blocks takeover. Give it search attributes, which takeover still refuses. Co-Authored-By: Claude Opus 5.5 --- rust/src/runtime/mysql.rs | 3 ++- rust/src/runtime/postgres.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rust/src/runtime/mysql.rs b/rust/src/runtime/mysql.rs index e4ab0a4fc..60b63da41 100644 --- a/rust/src/runtime/mysql.rs +++ b/rust/src/runtime/mysql.rs @@ -1389,7 +1389,8 @@ mod tests { "upgrade_source_external_payloads_unsupported", ), ( - "INSERT INTO workflow_schedules(id,schedule_id,namespace,spec,action,status,overlap_policy,jitter_seconds) VALUES ('s','nightly','default','{\"cron_expressions\":[\"0 2 * * *\"],\"timezone\":\"UTC\"}','{\"workflow_type\":\"echo\",\"task_queue\":\"default\"}','active','skip',0)", + // Native runs cron schedules; search attributes are still refused. + "INSERT INTO workflow_schedules(id,schedule_id,namespace,spec,action,status,overlap_policy,jitter_seconds,search_attributes) VALUES ('s','nightly','default','{\"cron_expressions\":[\"0 2 * * *\"],\"timezone\":\"UTC\"}','{\"workflow_type\":\"echo\",\"task_queue\":\"default\"}','active','skip',0,'{\"Customer\":\"acme\"}')", "upgrade_source_schedules_unsupported", ), ] { diff --git a/rust/src/runtime/postgres.rs b/rust/src/runtime/postgres.rs index 15d9d5082..0744d1ac0 100644 --- a/rust/src/runtime/postgres.rs +++ b/rust/src/runtime/postgres.rs @@ -922,7 +922,8 @@ mod tests { "upgrade_source_external_payloads_unsupported", ), ( - "INSERT INTO workflow_schedules(id,schedule_id,namespace,spec,action,status,overlap_policy,jitter_seconds) VALUES ('s','nightly','default','{\"cron_expressions\":[\"0 2 * * *\"],\"timezone\":\"UTC\"}','{\"workflow_type\":\"echo\",\"task_queue\":\"default\"}','active','skip',0)", + // Native runs cron schedules; search attributes are still refused. + "INSERT INTO workflow_schedules(id,schedule_id,namespace,spec,action,status,overlap_policy,jitter_seconds,search_attributes) VALUES ('s','nightly','default','{\"cron_expressions\":[\"0 2 * * *\"],\"timezone\":\"UTC\"}','{\"workflow_type\":\"echo\",\"task_queue\":\"default\"}','active','skip',0,'{\"Customer\":\"acme\"}')", "upgrade_source_schedules_unsupported", ), ] { From 8274a6f69971c3f9651d7227f98380d99ffd6701 Mon Sep 17 00:00:00 2001 From: Durable Workflow Date: Wed, 21 Oct 2026 08:33:09 +0000 Subject: [PATCH 2/3] Give database-job servers a writable /state for the storage diagnostic The storage-test fixture configures a local payload root under file:///state, which the SQLite job mounts but the MySQL and PostgreSQL jobs did not, so published PHP answered its round trip with 500. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/server-parity.yml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/server-parity.yml b/.github/workflows/server-parity.yml index c398c7358..ef4a5f2de 100644 --- a/.github/workflows/server-parity.yml +++ b/.github/workflows/server-parity.yml @@ -468,8 +468,10 @@ jobs: docker run --rm --user="$(id -u):$(id -g)" --entrypoint composer \ -e COMPOSER_HOME=/tmp/composer -v "$PWD:/source" -w /source "$image" \ install --working-dir=scripts/conformance/server-parity --no-interaction --no-progress + # The storage diagnostic writes local payloads under /state. + mkdir -p parity-state && chmod 0777 parity-state docker run -d --name "$RESOURCE_SCOPE-php" --network "$RESOURCE_SCOPE" --network-alias=parity-php \ - --user=1000:1000 --cpus=1 --memory=512m --memory-swap=512m \ + --user=1000:1000 --cpus=1 --memory=512m --memory-swap=512m -v "$PWD/parity-state:/state" \ -e DB_CONNECTION=mysql -e DB_HOST=parity-mysql -e DB_DATABASE=php_ref \ -e DB_USERNAME=root -e DB_PASSWORD=parity-disposable-password \ -e CACHE_STORE=file -e QUEUE_CONNECTION=database -e DW_AUTH_TOKEN=parity-test-token "$image" @@ -502,14 +504,14 @@ jobs: -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=mysql -e DB_HOST=parity-mysql -e DB_DATABASE=native_ref \ -e DB_USERNAME=root -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 docker run -d --name "$RESOURCE_SCOPE-native-b" --network "$RESOURCE_SCOPE" --network-alias=parity-native-b \ --user="$(id -u):$(id -g)" --cpus=1 --memory=256m --memory-swap=256m \ -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=mysql -e DB_HOST=parity-mysql -e DB_DATABASE=native_ref \ -e DB_USERNAME=root -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 ready=0 for attempt in $(seq 1 30); do @@ -634,7 +636,7 @@ jobs: -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=mysql -e DB_HOST=parity-mysql -e DB_DATABASE=native_ref \ -e DB_USERNAME=root -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 ready=0 for attempt in $(seq 1 30); do @@ -966,8 +968,10 @@ jobs: docker run --rm --user="$(id -u):$(id -g)" --entrypoint composer \ -e COMPOSER_HOME=/tmp/composer -v "$PWD:/source" -w /source "$image" \ install --working-dir=scripts/conformance/server-parity --no-interaction --no-progress + # The storage diagnostic writes local payloads under /state. + mkdir -p parity-state && chmod 0777 parity-state docker run -d --name "$RESOURCE_SCOPE-php" --network "$RESOURCE_SCOPE" --network-alias=parity-php \ - --user=1000:1000 --cpus=1 --memory=512m --memory-swap=512m \ + --user=1000:1000 --cpus=1 --memory=512m --memory-swap=512m -v "$PWD/parity-state:/state" \ -e DB_CONNECTION=pgsql -e DB_HOST=parity-pg -e DB_DATABASE=php_ref \ -e DB_USERNAME=parity -e DB_PASSWORD=parity-disposable-password \ -e CACHE_STORE=file -e QUEUE_CONNECTION=database -e DW_AUTH_TOKEN=parity-test-token "$image" @@ -999,14 +1003,14 @@ jobs: -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=pgsql -e DB_HOST=parity-pg -e DB_DATABASE=native_ref \ -e DB_USERNAME=parity -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 docker run -d --name "$RESOURCE_SCOPE-native-b" --network "$RESOURCE_SCOPE" --network-alias=parity-native-b \ --user="$(id -u):$(id -g)" --cpus=1 --memory=256m --memory-swap=256m \ -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=pgsql -e DB_HOST=parity-pg -e DB_DATABASE=native_ref \ -e DB_USERNAME=parity -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 ready=0 for attempt in $(seq 1 30); do @@ -1131,7 +1135,7 @@ jobs: -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=pgsql -e DB_HOST=parity-pg -e DB_DATABASE=native_ref \ -e DB_USERNAME=parity -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 ready=0 for attempt in $(seq 1 30); do From c136a129a21ce787eabfd7b4a114067485ca38c8 Mon Sep 17 00:00:00 2001 From: Durable Workflow Date: Wed, 21 Oct 2026 08:51:42 +0000 Subject: [PATCH 3/3] Use a per-container tmpfs for /state instead of a shared host directory The storage diagnostic only reads back what each server wrote, so every server can use its own writable /state without loosening host permissions. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/server-parity.yml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/server-parity.yml b/.github/workflows/server-parity.yml index ef4a5f2de..84a5eeebd 100644 --- a/.github/workflows/server-parity.yml +++ b/.github/workflows/server-parity.yml @@ -468,10 +468,8 @@ jobs: docker run --rm --user="$(id -u):$(id -g)" --entrypoint composer \ -e COMPOSER_HOME=/tmp/composer -v "$PWD:/source" -w /source "$image" \ install --working-dir=scripts/conformance/server-parity --no-interaction --no-progress - # The storage diagnostic writes local payloads under /state. - mkdir -p parity-state && chmod 0777 parity-state docker run -d --name "$RESOURCE_SCOPE-php" --network "$RESOURCE_SCOPE" --network-alias=parity-php \ - --user=1000:1000 --cpus=1 --memory=512m --memory-swap=512m -v "$PWD/parity-state:/state" \ + --user=1000:1000 --cpus=1 --memory=512m --memory-swap=512m --tmpfs /state \ -e DB_CONNECTION=mysql -e DB_HOST=parity-mysql -e DB_DATABASE=php_ref \ -e DB_USERNAME=root -e DB_PASSWORD=parity-disposable-password \ -e CACHE_STORE=file -e QUEUE_CONNECTION=database -e DW_AUTH_TOKEN=parity-test-token "$image" @@ -504,14 +502,14 @@ jobs: -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=mysql -e DB_HOST=parity-mysql -e DB_DATABASE=native_ref \ -e DB_USERNAME=root -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" --tmpfs /state --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 docker run -d --name "$RESOURCE_SCOPE-native-b" --network "$RESOURCE_SCOPE" --network-alias=parity-native-b \ --user="$(id -u):$(id -g)" --cpus=1 --memory=256m --memory-swap=256m \ -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=mysql -e DB_HOST=parity-mysql -e DB_DATABASE=native_ref \ -e DB_USERNAME=root -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" --tmpfs /state --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 ready=0 for attempt in $(seq 1 30); do @@ -636,7 +634,7 @@ jobs: -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=mysql -e DB_HOST=parity-mysql -e DB_DATABASE=native_ref \ -e DB_USERNAME=root -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" --tmpfs /state --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 ready=0 for attempt in $(seq 1 30); do @@ -968,10 +966,8 @@ jobs: docker run --rm --user="$(id -u):$(id -g)" --entrypoint composer \ -e COMPOSER_HOME=/tmp/composer -v "$PWD:/source" -w /source "$image" \ install --working-dir=scripts/conformance/server-parity --no-interaction --no-progress - # The storage diagnostic writes local payloads under /state. - mkdir -p parity-state && chmod 0777 parity-state docker run -d --name "$RESOURCE_SCOPE-php" --network "$RESOURCE_SCOPE" --network-alias=parity-php \ - --user=1000:1000 --cpus=1 --memory=512m --memory-swap=512m -v "$PWD/parity-state:/state" \ + --user=1000:1000 --cpus=1 --memory=512m --memory-swap=512m --tmpfs /state \ -e DB_CONNECTION=pgsql -e DB_HOST=parity-pg -e DB_DATABASE=php_ref \ -e DB_USERNAME=parity -e DB_PASSWORD=parity-disposable-password \ -e CACHE_STORE=file -e QUEUE_CONNECTION=database -e DW_AUTH_TOKEN=parity-test-token "$image" @@ -1003,14 +999,14 @@ jobs: -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=pgsql -e DB_HOST=parity-pg -e DB_DATABASE=native_ref \ -e DB_USERNAME=parity -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" --tmpfs /state --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 docker run -d --name "$RESOURCE_SCOPE-native-b" --network "$RESOURCE_SCOPE" --network-alias=parity-native-b \ --user="$(id -u):$(id -g)" --cpus=1 --memory=256m --memory-swap=256m \ -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=pgsql -e DB_HOST=parity-pg -e DB_DATABASE=native_ref \ -e DB_USERNAME=parity -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" --tmpfs /state --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 ready=0 for attempt in $(seq 1 30); do @@ -1135,7 +1131,7 @@ jobs: -e DW_RUST_EXPERIMENTAL=1 -e DW_AUTH_TOKEN=parity-test-token -e DW_BIND_ADDRESS=0.0.0.0:8080 \ -e DB_CONNECTION=pgsql -e DB_HOST=parity-pg -e DB_DATABASE=native_ref \ -e DB_USERNAME=parity -e DB_PASSWORD=parity-disposable-password \ - -v "$PWD/rust-target:/target:ro" -v "$PWD/parity-state:/state" --entrypoint /target/debug/durable-workflow-server \ + -v "$PWD/rust-target:/target:ro" --tmpfs /state --entrypoint /target/debug/durable-workflow-server \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 ready=0 for attempt in $(seq 1 30); do