Skip to content

Unify scheduled message store via PersistAsync#9616

Draft
PascalSenn wants to merge 3 commits intopse/adds-azure-serivce-ubsfrom
pse/unify-scheduled-message-store
Draft

Unify scheduled message store via PersistAsync#9616
PascalSenn wants to merge 3 commits intopse/adds-azure-serivce-ubsfrom
pse/unify-scheduled-message-store

Conversation

@PascalSenn
Copy link
Copy Markdown
Member

Summary

Collapses the two scheduling code paths in Mocha (middleware-store vs. endpoint-native) into a single resolver-routed IScheduledMessageStore.PersistAsync call. Removes SchedulingTransportFeature.SupportsSchedulingNatively.

  • IScheduledMessageStore.PersistAsync now takes IDispatchContext. The store reads envelope, scheduled time, transport, and endpoint from the context.
  • New IScheduledMessageStoreResolver selects the store for a scheduled dispatch by transport type and for cancellation by token prefix.
  • DispatchSchedulingMiddleware is always present in the default dispatch pipeline; resolves and invokes the right store at runtime.
  • Azure Service Bus and Postgres transports each register a transport-specific store; EfCoreScheduledMessageStore becomes the optional fallback for non-native transports.
  • AzureServiceBusDispatchEndpoint and PostgresDispatchEndpoint lose their ScheduledTime branches and become send-now terminals. Provisioning + entity-path resolution + message construction are extracted to shared helpers.
  • Scheduled dispatch to an unsupported transport now throws NotSupportedException instead of being sent immediately.

The full design rationale, alternatives considered, and trade-offs are in plan.md.

Test plan

  • dotnet build src/Mocha/Mocha.slnx — 0 errors
  • dotnet test src/Mocha/test/Mocha.Tests --filter "FullyQualifiedName~Scheduling|FullyQualifiedName~ScheduledMessage" — 45/45 pass on net8.0/net9.0/net10.0
  • Mocha.Transport.InMemory.Tests — 162/162 pass (covers redelivery + scheduling regressions)
  • Mocha.Sagas.Tests — 127/127 pass (saga timeouts via ScheduleSendAsync)
  • Resolver routing + registration validation unit tests
  • Squadron-fixture tests against real ASB broker — Mocha.Transport.AzureServiceBus.Tests/Behaviors/SchedulingTests.cs
  • Squadron-fixture tests against real Postgres — Mocha.Transport.Postgres.Tests/Behaviors/SchedulingTests.cs
  • RabbitMQ fixture tests (rewritten to assert the new throw contract)
  • EF Postgres integration tests
  • Session-aware ASB scheduled-dispatch integration test (locks the pipeline-order invariant)

Replace the SupportsSchedulingNatively dual-path with a single resolver
that routes scheduled dispatches and cancellations through one
IScheduledMessageStore per transport.

- IScheduledMessageStore.PersistAsync now takes IDispatchContext
- New IScheduledMessageStoreResolver picks the store by transport type
  for dispatch and by token prefix for cancellation
- DispatchSchedulingMiddleware always runs in the default pipeline
- Azure Service Bus and Postgres transports register transport-specific
  stores; EfCoreScheduledMessageStore is the optional fallback
- Endpoints lose the ScheduledTime branch and become send-now terminals
- SchedulingTransportFeature deleted
@PascalSenn PascalSenn marked this pull request as draft April 29, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant