Skip to content

Regression in 6.23.0: a paused per-database projection agent never resumes after RestartAgent (managed event-subscription distribution) #3663

Description

@jeremydmiller

Summary

In Wolverine 6.23.0, a projection/subscription agent that has been paused and then restarted never comes back. The agent stops correctly on pause, but the restart is accepted and the agent is never re-assigned to any node.

This works in 6.22.0-alpha.3 and fails in 6.23.0 with every other dependency held constant.

Isolation (single variable)

Same test, same clean database, Marten 9.20.0 / JasperFx 2.36.1 / Weasel 9.19.0 / Polecat 5.7.0 held fixed in all runs:

WolverineFx Result
6.22.0-alpha.3 ✅ 3/3 pass (2 runs)
6.23.0 ❌ 3/3 fail (2 runs)

So the regression is in Wolverine itself, not the Marten/JasperFx side of the bump.

Setup

  • Marten, database-per-tenant (sharded tenancy, 2 shard databases).
  • UseWolverineManagedEventSubscriptionDistribution, DurabilityMode.Balanced.
  • Each tenant database gets its own projection agent: event-subscriptions://marten/main/localhost.cw_shardN/trip/all.
  • Reproduces at nodeCount: 1 and 3 — it is not multi-node-specific.

Sequence

  1. Add tenant to shard; wait for that database's Trip agent to be running. ✅
  2. Pause the agent (a tenant-scoped pause resolving to that database's agent). ✅ agent stops as expected.
  3. Restart the agent. ❌ the agent never reappears in the running-agent set — 30 s timeout.

At the point of failure, agents for other tenants/shards are running normally, e.g.:

tenant-a Trip agent on cw_shard1 should resume after restart (timed out after 30s; expected present=True).
Cluster: node 1: [event-subscriptions://marten/main/localhost.cw_shard2/trip/all]

and on 3 nodes:

tenant-a Trip agent on cw_shard2 should resume after restart (timed out after 30s; expected present=True).
Cluster: node 1: [] | node 2: [event-subscriptions://marten/main/localhost.cw_shard1/trip/all] | node 3: []

So the grid is alive and distributing other agents — only the previously-paused one is never re-assigned.

Suspected area

The agent changes in 6.23.0, most plausibly one of:

  • d554b7230 — pending-assignment ledger suppresses duplicate AssignAgent floods (D3/D6)
  • a9d4a4de1 — scale-safe chunked, bounded-parallel agent batch starts (D3)
  • f703e1794 — ejection hysteresis + leader protection
  • 38fe0d317 — re-upsert assignment row for already-running agents (D4)

A plausible mechanism, given the symptom: the pause leaves a record that makes the restart's AssignAgent look like a duplicate/in-flight assignment, so the ledger suppresses it and the agent is never actually started. That would explain why the restart is accepted without error yet nothing starts, and why unrelated agents are unaffected.

Impact

Pause/restart of a projection agent is an operator action surfaced in CritterWatch, so on 6.23.0 an operator can pause a tenant's projection and be unable to resume it without a process restart.

Repro

EventStoreCoordinationTests.TenantPartitionedCoordinationTests in JasperFx/CritterWatch:

  • single_node_per_tenant_pause_then_restart
  • cluster_per_tenant_pause_then_restart
  • per_tenant_pause_is_isolated_from_other_tenants

Happy to help narrow it further or test a candidate fix.

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