Skip to content

[Bug]: Cancelling a queued subscription can release another active gateway turn lease #3549

Description

@CryoThrust

Description

HarnessGateway.withGatedTurn() and withGatedStream() allocate their AtomicReference<TurnLease> outside defer, so all subscriptions to the same returned publisher share the reference. Cancelling a second subscription while it waits for the session gate can close the first subscription's lease, although that first turn is still running. A subsequent turn can then enter the same session concurrently.

Reproduction

Verified on current main, febc795fc6afa6b3b81b2d6dde21dfca4f464374:

  1. Bind a fake agent whose call/stream stays active, using a real LocalSessionTurnGate wrapped only to observe acquisitions and lease closes.
  2. Obtain one publisher from gateway.run(...) or gateway.runStream(...) and subscribe once; wait until the first agent turn starts.
  3. Subscribe to that same publisher again; wait until the second gate acquisition starts while the first still holds it.
  4. Cancel only the second subscription.

Both provider-free controls fail: the cancelled waiter closes the first turn's lease. This is a public gateway-method test with a fake agent and real local gate, not a live provider/service test. The same two controls also fail on #3533's head, which has idempotent leases: idempotence cannot prevent the first, premature close by the wrong subscription.

Expected behavior / proposed fix

Each subscription should acquire and close only its own lease. I plan a small separate patch in HarnessGateway: keep acquisition inside defer, and attach cleanup to the turn publisher returned by that specific acquisition. Defer the supplied agent publisher as well so a synchronous supplier failure still releases the acquired lease.

This is separate from #3532/#3533's idle-map eviction and lease-idempotence change; it does not modify LocalSessionTurnGate.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions