Skip to content

Suppress misleading 'async daemon is disabled' warning under Wolverine-managed event subscription distribution (#3290)#3329

Closed
jeremydmiller wants to merge 1 commit into
mainfrom
fix/3290-misleading-daemon-disabled-warning
Closed

Suppress misleading 'async daemon is disabled' warning under Wolverine-managed event subscription distribution (#3290)#3329
jeremydmiller wants to merge 1 commit into
mainfrom
fix/3290-misleading-daemon-disabled-warning

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Closes #3290

Root cause

Marten's DocumentStore constructor writes this console warning whenever async projections are registered but StoreOptions.Projections.AsyncMode == DaemonMode.Disabled:

Warning: The async daemon is disabled.
Projections ... will not be executed without the async daemon enabled

UseWolverineManagedEventSubscriptionDistribution = true deliberately replaces Marten's AddAsyncDaemon(DaemonMode.HotCold) registration with WolverineProjectionCoordinator — but Marten's only knowledge of the daemon state is Projections.AsyncMode, which the integration never set. So it stayed Disabled, the warning fired for every store, and it was flatly wrong: the async projections DO run under Wolverine's managed distribution.

Fix

MartenOverrides — the IConfigureMarten hook the integration already registers for the main store and (via MartenOverrides<T>) every ancillary store — now records the real daemon state: when the resolved MartenIntegration has UseWolverineManagedEventSubscriptionDistribution enabled and AsyncMode is still Disabled, it sets AsyncMode = DaemonMode.HotCold, exactly what the AddAsyncDaemon(HotCold) call it replaces would have recorded.

Deliberately narrow:

  • Only upgrades from Disabled — an explicit user AddAsyncDaemon() choice is never overwritten (regardless of call order relative to IntegrateWithWolverine).
  • Projections.AsyncMode is purely descriptive here: Marten's own ProjectionCoordinator hosted service is only registered by AddAsyncDaemon() itself, so no Marten-side daemon gets started by this — the only Marten readers of the value are the warning gate and the coordinator Mode properties.
  • Stores without managed distribution warn exactly as before.

Tests

Bug_3290_misleading_daemon_disabled_warning (MartenTests) captures Console.Out around DocumentStore construction (the warning is a Console.WriteLine, not ILogger) and asserts:

  • managed distribution → AsyncMode == HotCold, no "The async daemon is disabled" output
  • no managed distribution → AsyncMode == Disabled, warning still emitted (behavior preserved)
  • managed distribution + explicit AddAsyncDaemon(Solo) → stays Solo

Verified locally: new tests green on net9.0 + net10.0; MartenTests.Distribution suite (26 tests — the managed-distribution mechanics that now see HotCold) and AncillaryStores suite (19 tests) green on net10.0.

🤖 Generated with Claude Code

…anaged distribution (GH-3290)

When UseWolverineManagedEventSubscriptionDistribution = true, Wolverine
replaces Marten's AddAsyncDaemon(DaemonMode.HotCold) registration with its
own WolverineProjectionCoordinator, but never told Marten so:
StoreOptions.Projections.AsyncMode stayed Disabled, and Marten's
DocumentStore constructor writes a "The async daemon is disabled ...
projections will not be executed" console warning whenever async
projections are registered with AsyncMode == Disabled — false and
alarming, since the projections DO run under Wolverine's distribution.

Fix: MartenOverrides (the IConfigureMarten hook that runs for the main
store and, via MartenOverrides<T>, every ancillary store) now sets
Projections.AsyncMode = DaemonMode.HotCold when the resolved
MartenIntegration has UseWolverineManagedEventSubscriptionDistribution
enabled and the mode is still Disabled. This mirrors what
AddAsyncDaemon(HotCold) — which the managed distribution replaces —
would have recorded, so Marten's warning gate no longer trips. An
explicit user AddAsyncDaemon() choice is never overwritten, and stores
without managed distribution still warn exactly as before.

Tests capture Console.Out around DocumentStore construction (the warning
is a Console.WriteLine, not ILogger) and assert: no warning + HotCold
under managed distribution, unchanged warning + Disabled without it, and
explicit AddAsyncDaemon(Solo) preserved.

Closes #3290

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jeremydmiller

Copy link
Copy Markdown
Member Author

Closing per review: setting AsyncMode = HotCold from the integration is wrong — it records a mode that turns Marten's own daemon coordination on in parallel with Wolverine's managed distribution.

Correct design instead: a fourth DaemonMode enum value, ExternallyManaged — no warnings from the store, no store-hosted coordination, and Wolverine's MartenIntegration sets it explicitly (same for the Polecat integration, which most likely has the same issue). Chain: JasperFx enum + core handling → Marten (warning gate + coordinator registration) → Wolverine integration sets it → Polecat parity. The test coverage from this PR (console capture, explicit-user-choice preservation) carries into the redo. Tracked under JasperFx/jasperfx#486 / wolverine#3290.

🤖 Generated with Claude Code

jeremydmiller added a commit that referenced this pull request Jul 7, 2026
…ine-managed distribution (closes #3290) (#3330)

* Record DaemonMode.ExternallyManaged under Wolverine-managed event subscription distribution (#3290)

UseWolverineManagedEventSubscriptionDistribution replaces Marten's own
AddAsyncDaemon() coordination outright, but Marten's only knowledge of the
daemon state is Projections.AsyncMode. Left at Disabled, DocumentStore wrote
a misleading "The async daemon is disabled ... projections will not be
executed" console warning at startup even though Wolverine IS running the
async projections.

MartenOverrides (the IConfigureMarten hook covering the main store and, via
MartenOverrides<T>, every ancillary store) now records the real state as
DaemonMode.ExternallyManaged (#490): identical runtime posture to
Disabled — Marten hosts no coordinator and starts no agents — but the
warning gate stays quiet because the external host runs the projections.
Only upgrades from Disabled, so an explicit user AddAsyncDaemon() choice is
never overwritten in either call order.

Replaces the closed #3329, whose AsyncMode = HotCold approach was rejected
for implying Marten's own coordination runs in parallel.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Record DaemonMode.ExternallyManaged for Polecat under Wolverine-managed distribution (#3290)

Polecat parity with the Marten side: UseWolverineManagedEventSubscriptionDistribution
replaces Polecat's own AddAsyncDaemon()/AddProjectionCoordinator() hosting outright,
but the store's only knowledge of the daemon state is DaemonSettings.AsyncMode,
which the integration never set. PolecatOverrides (main store) and
PolecatOverrides<T> (ancillary stores, deferring to the main PolecatIntegration
flag exactly like the IProjectionCoordinator<T> factory does) now record
DaemonMode.ExternallyManaged (#490): identical runtime posture to Disabled —
nothing Polecat-hosted starts — while any AsyncMode reader sees that async
projections DO run under Wolverine's distribution. Only upgrades from Disabled,
so an explicit user daemon choice is never overwritten in either call order.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Consume JasperFx 2.21.0 (DaemonMode.ExternallyManaged, #490)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.

Misleading 'async daemon is disabled' warning with UseWolverineManagedEventSubscriptionDistribution = true

1 participant