Repository navigation
Register the event-subscription family aliases from the ancillary Marten path (GH-3438) - #3451
Merged
jeremydmiller merged 1 commit intoJul 17, 2026
Conversation
…ten path (GH-3438) The main-store integration aliases EventSubscriptionAgentFamily to IAgentFamily and IEventSubscriptionAgentFamily; the ancillary integration registered only the concrete type, with a standing "watch the service registrations" TODO. So a host whose only store wanting managed distribution is ancillary - no main AddMarten that opts in - registered no IEventSubscriptionAgentFamily at all. Wolverine's managed distribution and external tooling (CritterWatch's projection admin) that resolve the family through the interface got nothing. AncillaryMartenIntegration gains a UseWolverineManagedEventSubscriptionDistribution flag mirroring the main store's. When set, the ancillary path registers the two interface aliases via TryAddSingleton - Try so a main store that already aliased them wins and one family instance (it already takes IEnumerable<IEventStore>) covers every store. The aliases are gated on the flag because NodeAgentController distributes the agents of every registered IAgentFamily; an ancillary host that never opted in must not suddenly start distributing. The per-store projection coordinator resolver also consults the ancillary flag now, not just the main MartenIntegration, so an ancillary-only host gets the managed WolverineProjectionCoordinator<T> rather than silently falling back to the non-managed coordinator. Test: an ancillary store opts in while the main store deliberately does not, so any family resolving through the interface must come from the ancillary path. Verified the three assertions fail with the flag present but the registration absent, and the existing with_ancillary_stores tests still pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3438.
The gap
The main-store integration aliases
EventSubscriptionAgentFamilyto bothIAgentFamilyandIEventSubscriptionAgentFamily. The ancillary integration registered only the concrete type, with a standing// TODO -- watch the service registrations. So a host whose only store wanting managed distribution is ancillary — no mainAddMartenthat opts in — registered noIEventSubscriptionAgentFamily. Wolverine's managed distribution and external tooling (CritterWatch's projection admin: rebuild/pause/restart) resolve the family through that interface and got an empty result.What I found beyond the issue
The issue's repro assumes an
AncillaryMartenIntegration.UseWolverineManagedEventSubscriptionDistributionflag — which didn't exist. And the per-storeIProjectionCoordinator<T>resolver only consulted the mainMartenIntegration, which is null/absent for an ancillary-only host. So the fix is three coordinated parts, not a one-line alias add:UseWolverineManagedEventSubscriptionDistributiononAncillaryMartenIntegration, mirroring the main store's. This is the opt-in an ancillary-only host previously had no way to express.TryAddSingleton—Tryso a main store that already aliased them wins and one family instance (it already takesIEnumerable<IEventStore>) covers every store. Gated on the flag becauseNodeAgentControllerdistributes the agents of every registeredIAgentFamily; an ancillary host that never opted in must not suddenly start distributing.WolverineProjectionCoordinator<T>instead of silently falling back to the non-managed coordinator.Test
ancillary_managed_distribution_family_registration: an ancillary store opts in while the main store deliberately does not, so any family resolving through the interface must come from the ancillary path. Asserts the family resolves throughIEventSubscriptionAgentFamily, is present as anIAgentFamilyfor distribution, and that the ancillary store gets the managed coordinator.Verified red/green: with the flag present but the registration reverted, all three assertions fail; with the fix they pass. The existing
with_ancillary_storestests (main+ancillary) still pass — no regression on that path. Fullwolverine.slnxbuilds clean (0 warnings).Note: one unrelated multi-node failover test (
tenant_partitioned_distribution_multinode.agents_fail_over...) flaked under full-suite load and passes in isolation; it uses a main store, not ancillary, so it's untouched by this change.🤖 Generated with Claude Code