Skip to content

Document + test that FindAgentUriAsync resolves registered (not just live) projection shards (#3124)#3126

Merged
jeremydmiller merged 1 commit into
mainfrom
fix-3124-registered-agent-uri
Jun 17, 2026
Merged

Document + test that FindAgentUriAsync resolves registered (not just live) projection shards (#3124)#3126
jeremydmiller merged 1 commit into
mainfrom
fix-3124-registered-agent-uri

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Context

#3124 asks that IEventSubscriptionAgentFamily.FindAgentUriAsync(shardIdentity, tenantId, ct) be able to resolve a projection/subscription shard that is registered but not currently running (paused, stopped, crashed, or pre-start), so that admin operations (pause/restart/rebuild) can act on a non-running projection — which is exactly when they're needed.

Finding

On current main, FindAgentUriAsync already does this. It resolves from the registered subscription set:

FindAgentUriAsync → SupportedAgentsAsync() → EventStoreAgents.SupportedAgentsAsync()
                  → usage.Subscriptions.Where(Lifecycle == Async).SelectMany(ShardNames)

That set is the registered projection graph and is independent of run state, so a paused/stopped/not-yet-started shard still resolves. This behavior arrived with the event-subscription agent family in #3108 (after the 6.11.0 the issue was filed against).

The remaining problem was the contract documentation: both the interface and the Marten implementation still described the method as resolving the "live agent" and returning null when "no matching live agent is found" — the precise wording #3124 calls out as wrong/misleading.

Changes

  • Correct the XML docs on IEventSubscriptionAgentFamily.FindAgentUriAsync and the Marten EventSubscriptionAgentFamily to state the run-state-independent (registered) behavior.
  • Add regression tests (find_agent_uri_for_registered_projection) proving a registered shard resolves to its agent URI without a running agent, and that an unregistered shard returns null. Both pass.

Out of scope (noted for follow-up)

FindAgentUriAsync with a non-null tenantId currently handles only single-database per-tenant partitioning (tenant in the shard RelativeUrl). Database-per-tenant resolution (tenant → separate database, e.g. MultiTenantedWithShardedDatabases) needs a tenant→database mapping and is still deferred — happy to take that on as a separate change if CritterWatch needs per-tenant resolution in the sharded-database model.

🤖 Generated with Claude Code

…st live) projection shards (#3124)

IEventSubscriptionAgentFamily.FindAgentUriAsync already resolves the agent URI from
the *registered* subscription set (via SupportedAgentsAsync -> usage.Subscriptions),
so it succeeds for a projection whose agent is paused/stopped/crashed/not-yet-started
— exactly what lets an operator restart or rebuild a non-running projection. That was
delivered with the event-subscription agent family in #3108.

But the XML docs on both the interface and the Marten implementation still described it
as resolving the "live agent" and returning null when "no matching live agent is found",
which is the precise contradiction #3124 reported. This corrects the contract docs to
state the run-state-independent (registered) behavior and adds regression tests proving
a registered shard resolves without a running agent (and that an unregistered shard
returns null).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jeremydmiller jeremydmiller merged commit b3a58de into main Jun 17, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant