Skip to content

Default queue workers skip repair for tasks with an implicit connection #751

Closed

Description

@rmcdaniel

Customer-visible problem

Embedded workflows using the application's default queue connection can remain pending after a transient task-claim failure or lost queue envelope. The normal queue-worker repair loop filters by the resolved connection name, while those durable tasks can store an implicit connection as null.

With QUEUE_CONNECTION=redis, a Laravel worker emits Looping(connectionName: redis, queue: default). TaskWatchdog passes that scope to RequestedTaskScope, which matches connection=redis exactly. A task storing connection=null is dispatched through Redis by default but excluded from this repair scan. The symbolic default scope does include it.

Verified diagnostic

The trusted SQLite handoff from PR #749 reproduced on unchanged published-tag source 2.5.7, commit e9a767b08c426234c25d2969adcb09473e7af56e, with PHP 8.3.35, Laravel 13.35.0, PHPUnit 12.5.38 and the same generated development dependency identities as the original control. The package intentionally does not commit composer.lock.

  • Three parents each start four children, each completing one activity, through two real Redis queue workers and an isolated SQLite database.
  • The original feature harness disables automatic repair for 600 seconds. Its ordinary 30-second timeout alone does not prove a recovery defect.
  • Removing only that V2 suppression still reproduced pending parents with ready, unclaimed tasks and no repair attempt within the timeout. Actual SQLite task claims raised database is locked.
  • A further bounded probe confirmed default queue redis, queue wake enabled, a registered Looping listener and an actual Redis/default worker heartbeat. taskIds(connection: redis, queue: default) selected zero while taskIds(connection: default, queue: default) selected the two pending tasks. A forced Redis-scoped pass selected/dispatched zero. A default-scoped pass selected/dispatched both with no repair failure.
  • One default pass recovered the initial parents, but later child contention required further repair. That run failed a later timeout after 11 assertions. It is partial recovery evidence, not a passing concurrency qualification.

This identifies a scope mismatch. It does not establish indefinite loss under every deployment, qualify full SQLite concurrency, or implicate the version-range correction in #744.

Acceptance

  • A worker on the configured default connection repairs overdue durable tasks and missing resume work that inherited that connection, including null/empty/default representations supported by the existing contract.
  • Explicit tasks on another connection or queue remain excluded. Preserve comma-separated scope selection and existing explicit/default scope behavior.
  • Apply the same effective connection semantics to scoped deadline/timeout scans that use the shared selector.
  • Add focused regression checks and verify the original three-parent/twelve-child case with normal repair enabled, exact source/runtime identities, bounded resources and no duplicate activity completion.
  • Run normal repository quality and SQL checks, publish the patch and verify affected embedded/pinned consumers. Keep concurrent Rust Server qualification inputs immutable and coordinate its downstream pin.

Priority P1 because this affects ordinary embedded recovery. General product owner implements this independently of Server #325 and coverage #426.

Activity

  1. added
    kind:defectA public product behavior is incorrect
    priority:P1High-priority product or release risk
    intake:approvedCurrent issue title and body revision is approved for authority intake
    status:in-progressApproved work is actively being implemented or validated
    on Oct 11, 2026
  2. rmcdaniel commented on Oct 11, 2026

    @rmcdaniel
    MemberAuthor

    Implemented in PR #752, merged 82a244cab0f95cb2ebe4592bccbfb5a6aab08c77. Its tree f5a8497b4545bbd0ca93f3e59ff8f3c1e2c6ae5a exactly matches the reviewed head. All 11 applicable PR checks pass, with five intentional target-only skips.

    The final changed-feature MySQL job executes the new lost-envelope recovery case with 14 assertions, completing in 1.813 seconds, alongside the existing parallel-child cases. The actual SQLite candidate and exact old-selector negative control are documented in the PR. The fix changes default connection selection and preserves other queues/connections and existing lease defaults.

    Full main qualification 38117371321 is running before 2.5.9 publication. This issue stays open for the published-package regression and affected pinned consumers. The merged remote/local branch is removed. No active diagnostic runtime remains.

  3. rmcdaniel commented on Oct 11, 2026

    @rmcdaniel
    MemberAuthor

    Workflow 2.5.9 is published at 82a244cab0f95cb2ebe4592bccbfb5a6aab08c77. Packagist source/dist references and the fresh normal Composer installation match that commit and report runtime release 2.5.9.

    • Full source qualification passes all 23 applicable main checks, with two PR-only skips. This includes all MySQL/PostgreSQL shards, MariaDB, quality/static analysis, regression corpus and Laravel 9–13 source upgrade cases. The full unit suite executes 3,795 tests / 49,209 assertions, with five skips and fifteen notices. V2 line coverage is 93.47%, above its accepted 93.08% baseline.
    • Published-package verification passes the package contract and all 16 Laravel/PHP upgrade cells.
    • A fresh normal Composer dist installation has all 918 tracked source/resource files and composer.json byte-identical to the qualified source. The focused real-worker regression runs with those installed source/resource files mounted read-only, with the existing Testbench development harness. On SQLite, PHP 8.3.35, Laravel 13.35.0, one CPU / 1 GiB and unchanged default leases, it passes 14 assertions in 2.769 seconds of test time. The fixture drops the initial envelope and ages its dispatch timestamps to make it overdue. Ordinary worker Looping events repair the original task, complete the original run with one activity attempt and single completion events, and leave no run failure. Container exit is zero with no OOM. The previously retained exact old-selector control stays pending with zero repair.

    The complete source/publication qualification and its runtime containers, Redis, network, installed dependencies and 309 MiB scratch are now cleaned up. Existing tags and the Rust owner's Server 2.5.18 / Workflow 2.5.8 cohort remain unchanged.

    This issue remains open for the Sample App pinned consumer and documentation update, plus coordinated PHP Server adoption after its current release. SDK versions do not need a release for this embedded connection-selection fix.

  4. rmcdaniel commented on Oct 11, 2026

    @rmcdaniel
    MemberAuthor

    The next pinned Server consumer is Server #390, preparing Server 2.5.19 with published Workflow 2.5.9. This ordinary PHP update is coordinated with the Rust Server owner after completing its separate Server 2.5.18 release. All other Composer packages retain their exact entries.

    Sample App #196 is qualifying both embedded locks. Website #209 passed all four checks and merged, with deployment verification next.

    Waterline's Workflow dependency is development-only. Its standalone production image uses the SDK, and embedded applications supply their own Workflow package. No Waterline or SDK release is needed for this connection selection fix. The sample's actual Waterline HTTP and MCP integration qualifies the affected embedded consumer.

  5. rmcdaniel commented on Oct 11, 2026

    @rmcdaniel
    MemberAuthor

    Delivered at c04481db59446a380deb0e9efb22abf1a5326ac0, with the exact qualified tree. Both locks install Workflow 2.5.9 at 82a244cab0f95cb2ebe4592bccbfb5a6aab08c77.

    • All 18 PR and 20 main checks pass, including PHP 8.4/8.5 app and microservice checks, the actual Waterline HTTP/MCP integration and existing SDK/recovery scenarios.
    • Native image publication passes both architectures, actual platform qualification and main promotion.
    • Both registries' main and immutable tag sha-c04481db59446a380deb0e9efb22abf1a5326ac0-run-38120102329-1 have the same index sha256:5d28ba758e169d5d7609d6f0bb1c3a6ad838f08a8307dd1c9ad7fb25d8d439f5. Raw platform manifest/config hashes, architectures and source revision verify.

    The development image is durableworkflow/sample-app-devcontainer on Docker Hub and ghcr.io/durable-workflow/sample-app-devcontainer on GHCR. The completed branch and temporary checkout are removed. Server and SDK qualification pins retain their selected versions.

  6. rmcdaniel commented on Oct 11, 2026

    @rmcdaniel
    MemberAuthor

    Workflow 2.5.9 and its pinned consumers are delivered.

    The recovery fix is released and available through the documented artifacts. Qualification covers the PHP package and published PHP Server. Rust Server development and managed Cloud adoption follow their separate owning work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    intake:approvedCurrent issue title and body revision is approved for authority intakekind:defectA public product behavior is incorrectpriority:P1High-priority product or release riskstatus:in-progressApproved work is actively being implemented or validated

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions