Skip to content

Marten: foundation re-pin + adopt lifted async-daemon distributors + cut 9.0.0-alpha.5#4511

Merged
jeremydmiller merged 3 commits into
masterfrom
chore/foundation-realign-and-distributor-dedupe
May 19, 2026
Merged

Marten: foundation re-pin + adopt lifted async-daemon distributors + cut 9.0.0-alpha.5#4511
jeremydmiller merged 3 commits into
masterfrom
chore/foundation-realign-and-distributor-dedupe

Conversation

@jeremydmiller
Copy link
Copy Markdown
Member

Closes the "Async daemon abstractions — confirm Marten consumes the JasperFx.Events 2.0 versions; remove any Marten-side fork" dedupe row and the "Cut Marten 9.0.0-alpha.5" foundation re-pin from Marten#4349. Sibling to Polecat #118 (interfaces) + Polecat #119 (concretes).

Foundation re-pin

Package From To
JasperFx 2.0.0-alpha.17 2.0.0-alpha.20
JasperFx.Events 2.0.0-alpha.16 2.0.0-alpha.20
JasperFx.Events.SourceGenerator 2.0.0-alpha.9 2.0.0-alpha.12
JasperFx.SourceGeneration 2.0.0-alpha.6 2.0.0-alpha.9
Weasel.Postgresql / Weasel.EntityFrameworkCore 9.0.0-alpha.6 9.0.0-alpha.7
Marten 9.0.0-alpha.4 9.0.0-alpha.5

JasperFx.Events is pinned at alpha.20 rather than the chip's alpha.19 — the SingleTenantProjectionDistributor lift (JasperFx #320) only shipped in alpha.20. Weasel alpha.7 is load-bearing: its AdvisoryLock now implements JasperFx.Events.Daemon.IAdvisoryLock directly (nuspec picks up a JasperFx.Events 2.0.0-alpha.19 dep), which is what lets Marten pass it straight to the lifted distributors with no wrapper. JasperFx.RuntimeCompiler is not referenced by any Marten csproj (retired in #4454), so there was no RC pin to bump.

Distributor dedupe

Deleted (Marten-local):

  • Events/Daemon/Coordination/IProjectionDistributor.cs
  • Events/Daemon/Coordination/IProjectionSet.cs
  • Events/Daemon/Coordination/SoloProjectionDistributor.cs
  • Events/Daemon/Coordination/SingleTenantProjectionDistributor.cs
  • Events/Daemon/Coordination/MultiTenantedProjectionDistributor.cs

Adopted from JasperFx.Events.Daemon: IProjectionDistributor, IProjectionSet, IProjectionDatabase, and the Solo / SingleTenant / MultiTenanted concretes.

Consumption-site changes:

  • MartenDatabase : IProjectionDatabaseIdentifier comes from the Weasel DatabaseBase; DatabaseUri is an explicit-interface impl returning the canonical descriptor URI (off the public surface, never hit on the daemon hot path).
  • ProjectionSet retained as the Marten-side IProjectionSet implementation; dead BuildDaemon() dropped (no callers, not part of the lifted contract).
  • ProjectionCoordinator.BuildDistributor constructs the lifted distributors with closures over Marten's tenancy (Storage.AllDatabases / Storage.Database), shards (Projections.AllShards), the Postgres lock factory (Weasel AdvisoryLock), the ProjectionSet factory, the event schema name (SingleTenant lock-id qualifier), and DaemonLockId.

Lock-id formula is unchanged: the lifted SingleTenantProjectionDistributor routes through ProjectionLockIds.Compute(schema, shard, baseLockId), byte-identical to Marten's prior Math.Abs(hash)+DaemonLockId.

Verification

  • dotnet build src/Marten.slnx -c Release — 0 errors (net9 + net10).
  • DaemonTests: 185 passed / 0 failed / 0 skipped (net10).
  • EventSourcingTests: 1322 passed / 0 failed / 6 skipped (net10).
  • DaemonTests.ManualOnly (run one test at a time): 10 passed, 15 failed — all 15 failures verified pre-existing on master, none caused by this change:
    • 11 are InvalidProjectionException: No source-generated dispatcher found (BlueProjection / GreenProjection / FakeSingleStream*Projection aren't partial — bit-rotted ManualOnly fixtures; fail identically on clean master).
    • 4 are flaky multi-daemon daemon.IsRunning leadership timing assertions; all fail on clean master too (single-daemon HotCold + AdvisoryLocks tests, which exercise the new distributors on the happy path, pass).
  • Marten.AotSmoke builds + runs clean (no new IL warnings from the changed files).
  • ModularConfigTests — 5/5 (PR Marten#4472: Modular composite configuration smoke + behavior tests across satellite assemblies #4495 gate).

Follow-up (out of scope, not a regression here)

DaemonTests.ManualOnly's BlueProjection / GreenProjection / FakeSingleStream*Projection fixtures need to be made partial (+ the project needs the JasperFx.Events.SourceGenerator analyzer) to satisfy the post-#276 source-gen dispatcher requirement. They've bit-rotted since that landed because the project is excluded from CI. Worth a separate clean-up issue.

🤖 Generated with Claude Code

jeremydmiller and others added 3 commits May 19, 2026 16:57
… SourceGeneration alpha.9 + Weasel alpha.7

Weasel 9.0.0-alpha.7 is required (not just newer): its AdvisoryLock now
implements JasperFx.Events.Daemon.IAdvisoryLock directly (the nuspec picks
up a JasperFx.Events 2.0.0-alpha.19 dependency), which unblocks adopting
the lifted *ProjectionDistributor concretes in the following commits.

JasperFx.RuntimeCompiler is not referenced by any Marten csproj (retired in
#4454), so there is no RC pin to bump.

src/Marten builds clean across net9/net10.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nDatabase + *ProjectionDistributor concretes from JasperFx.Events

Bumps JasperFx.Events alpha.19 -> alpha.20 (the alpha that ships the
SingleTenantProjectionDistributor lift, JasperFx #320).

Interfaces (Phase 2):
- Delete Marten-local IProjectionDistributor.cs / IProjectionSet.cs; consume
  the JasperFx.Events.Daemon canonical versions.
- MartenDatabase now implements IProjectionDatabase (Identifier comes from the
  Weasel DatabaseBase; DatabaseUri is the canonical descriptor URI, explicit
  interface impl, off the public surface and never hit on the daemon hot path).
- ProjectionSet keeps its Marten-side concrete role (implements the lifted
  IProjectionSet); BuildDaemon() dropped — it had no callers and isn't part of
  the lifted contract.

Concretes (Phase 3):
- Delete Marten's Solo/SingleTenant/MultiTenanted distributors.
- ProjectionCoordinator.BuildDistributor wires the JasperFx.Events versions with
  closures over Marten's tenancy (AllDatabases / Storage.Database), shards
  (Projections.AllShards), the Postgres lock factory, the ProjectionSet factory,
  the event schema name (SingleTenant lock-id qualifier), and DaemonLockId.
- The lock factory returns Weasel.Postgresql.AdvisoryLock, which implements
  JasperFx.Events.Daemon.IAdvisoryLock directly as of Weasel 9.0.0-alpha.7 — no
  wrapper needed.

Lock-id formula is unchanged: the lifted SingleTenant routes through
ProjectionLockIds.Compute(schema, shard, baseLockId), byte-identical to Marten's
prior Math.Abs(hash)+DaemonLockId.

Full solution builds clean across net9/net10.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Foundation re-pin + async-daemon distributor dedupe alpha. AOT smoke builds
and runs clean; modular-config gate green (5/5).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jeremydmiller jeremydmiller merged commit 76a15a9 into master May 19, 2026
6 checks passed
@jeremydmiller jeremydmiller deleted the chore/foundation-realign-and-distributor-dedupe branch May 19, 2026 22:54
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