Skip to content

WorkerPollFence keeps an old poll current across a same-second or same-process re-registration #749

Open

Description

@rmcdaniel

Defect

Published Server 2.11.1's WorkerPollFence decides whether a held workflow, activity or query poll still belongs to the registration it started under. It compares the routing revision, plus either the reported process identity (host, process ID, process start) or the registration's updated_at / last_heartbeat_at. Both of those are stored in whole seconds.

It never consults anything unique to a registration. So an old poll stays current, and can lease work meant for the replacement process, when a same-ID re-registration:

  • reports the same process metadata (for example a retry or re-registration from the same process), at any time; or
  • reports no process metadata and lands in the same stored second as the previous registration or heartbeat.

Security reported this in the Rust port's review (Server #739, #739 (comment)). The published path shares the heuristic.

Expected

Each registration is a distinct incarnation. A same-ID re-registration ends every poll held under the previous one, whatever its metadata and timing. A heartbeat keeps the incarnation.

Boundary in the Rust port

Native already rotates a unique incarnation token on every registration and keeps it across heartbeats. Native's fence now requires the snapshotted token to still be the active one, on top of PHP's checks, so native is stricter only in the two cases above.

The shared worker-poll-fence fixture never takes either path: each PHP re-registration it records lands in a later second with different metadata. So it compares equal on both implementations. Native regression tests cover same-process and same-second re-registration for workflow, activity and query polls.

Suggested PHP fix: snapshot the registration's unique incarnation (or an equivalent value that rotates on every registration but not on heartbeats) at admission, and require it in isCurrent / isCurrentForUpdate.

Activity

  1. added a commit that references this issue on Oct 24, 2026
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