Skip to content

EventSubscriptionAgent.RebuildAsync/RewindAsync leave the shard permanently stopped under Wolverine-managed distribution (daemon stops continuous agents; nothing restarts them) #3520

Description

@jeremydmiller

Wolverine 6.21.0 / JasperFx.Events 2.30.1. Found via JasperFx/CritterWatch#747 (every console-driven rebuild left the projection dead); root-caused with a deterministic repro.

RebuildAsync (and RewindAsync) leave the shard permanently stopped under Wolverine-managed event-subscription distribution

EventSubscriptionAgent.RebuildAsync delegates to _daemon.RebuildProjectionAsync(...). JasperFx's daemon-level rebuildProjection:

  1. stopRunningAgents(subscriptionName) — stops the running continuous agents;
  2. rebuilds via transient agents;
  3. stops-and-drains those transient agents;
  4. never restarts what it stopped in (1).

Under a store-owned daemon (AddAsyncDaemon) the store's coordinator loop notices the stopped shard and resurrects it. Under Wolverine-managed distribution there is no store coordinator — and Wolverine's EventSubscriptionAgent.Status still reads Running (the wrapper never observed a stop), so NodeAgentController sees nothing to fix. Net: after every rebuild the shard re-registers RegisteredIdle daemon-side and freezes forever while the high-water mark climbs. An operator "Restart" that routes to an agent Wolverine believes is already running no-ops.

RewindAsync has the same end state via a different mechanism: JasperFxAsyncDaemon.RewindSubscriptionAsync does restart agents after rewinding — but it builds them with buildAgentsForSubscription(...) and StartAsyncs them directly, bypassing tryStartAgentAsync, so they never register in _agents and the wolverine wrapper's _innerAgent still points at the stopped one.

Repro

Deterministic: rebuild any async projection while its publisher keeps appending on a Wolverine-managed-distribution host, then watch the progression row freeze while the HWM climbs. (Rebuilding with a stopped publisher hides the defect — a caught-up shard and a stalled shard are indistinguishable with no event flow, which is why simpler rebuild tests pass.) CritterWatch pins this with projection_rebuild_under_load (JasperFx/CritterWatch@02c49251): red on stock behavior, green with the workaround.

Workaround (CritterWatch side, revert candidate)

Both CritterWatch handlers now call agent.StartAsync(ct) immediately after RebuildAsync/RewindAsync — resuming continuous mode through the registered path.

Suggested fix

EventSubscriptionAgent.RebuildAsync/RewindAsync should restore continuous execution themselves (re-run the StartAsync path after the daemon-level operation), or the daemon-level operations should restart what they stopped through the registered path (see the companion JasperFx issue for that half).

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