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:
stopRunningAgents(subscriptionName) — stops the running continuous agents;
- rebuilds via transient agents;
- stops-and-drains those transient agents;
- 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).
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.RebuildAsyncdelegates to_daemon.RebuildProjectionAsync(...). JasperFx's daemon-levelrebuildProjection:stopRunningAgents(subscriptionName)— stops the running continuous agents;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'sEventSubscriptionAgent.Statusstill readsRunning(the wrapper never observed a stop), soNodeAgentControllersees nothing to fix. Net: after every rebuild the shard re-registersRegisteredIdledaemon-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.RewindAsynchas the same end state via a different mechanism:JasperFxAsyncDaemon.RewindSubscriptionAsyncdoes restart agents after rewinding — but it builds them withbuildAgentsForSubscription(...)andStartAsyncs them directly, bypassingtryStartAgentAsync, so they never register in_agentsand the wolverine wrapper's_innerAgentstill 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 afterRebuildAsync/RewindAsync— resuming continuous mode through the registered path.Suggested fix
EventSubscriptionAgent.RebuildAsync/RewindAsyncshould restore continuous execution themselves (re-run theStartAsyncpath 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).