Repository navigation
Marten 9.34.0
Native AOT support for event-sourced applications, and a round of integrity fixes to the diagnostics and monitoring surface — including one deliberate behaviour change worth reading before upgrading.
Native AOT
Event-sourced applications now run under Native AOT.
- #5375 — Closes four generics where the compiler can emit them, so an event-sourced app runs under Native AOT rather than failing at runtime on a construction the trimmer removed.
- #5377 — The jsonb containment payload is written by Marten with
Utf8JsonWriterinstead of round-tripping through the consumer's serializer, removing a reflection-dependent path from AOT reads.
Diagnostics and monitoring
Three fixes to the event store explorer and projection-status APIs. All three are cases where a monitoring read returned something misleading, or changed the system it was observing.
-
#5400 — Behaviour change. The four explorer read APIs no longer provision anything. They resolved their database through
ITenancy.FindOrCreateDatabase, and two tenancy models take the "or create" half literally:ShardedTenancyassigned an unknown tenant to a shard and ran partition + per-tenant sequence DDL for it, andSingleServerMultiTenancyissuedCREATE DATABASEfor a database named after the id. A console polling a retired or mistyped tenant id therefore brought that tenant — or a whole database — into existence.An unrecognized tenant id now throws
UnknownTenantIdException, which is whatStaticMultiTenancyandMasterTableTenancyalready did, so the explorer answers the same way across every tenancy model. Adds the publicITenancy.TryFindDatabase, a read-only counterpart toFindOrCreateDatabase; it is a default interface member, so customITenancyimplementations keep working unchanged.FindOrCreateDatabaseitself is untouched — create-on-demand remains its documented job for real tenant traffic.If you call
GetRecentStreamsAsync,ReadStreamAsync,QueryByTagsAsyncorGetProjectionStatusesAsyncwith a tenant id that may not exist, it now throws where it previously succeeded. -
#5382 —
GetProjectionStatusesAsync(ct)threwNotSupportedExceptionon a database-per-tenant store, because a tenant-less call has no default tenant to open a session against. It now answers from the projection registry, so "is this projection still registered?" — the only store-agnostic way to ask, and what orphan detection is built on — works on the store shape that most needs it.Note the original issue reported that both overloads threw. Only the tenant-less one did; passing a tenant id or a database identifier from
AllDatabases()has always worked and reads real per-database progression. -
#5396 —
ShardStatus.Statereports the state of a reachable daemon instead of always answeringUnknown.Unknownnow means what it is documented to mean: there is no daemon here to ask.
Correctness
- #5386 — The expected version for optimistic concurrency is seeded from a mapped version/revision member, not just the
IVersionedmarker interface. Thanks to @JurJean for the report and the original fix. - #5389 — Enum member renames are resolved by asking the serializer, so
[JsonStringEnumMemberName]/[EnumMember]names are honored in LINQ translation rather than the CLR member name being assumed. - #5390 — The jsonb containment payload writer handles nested dictionary keys and
byte[], and its limits are documented. Thanks to @erdtsieck.
Event modeling
- #5397 —
ProjectionEventModelSourceis registered fromAddMartenandAddMartenStore<T>, so Event Model views resolve from a Marten store without manual wiring.
pgvector
- #5399 — Four defects the pgvector import left behind.
Docs and internals
- #5381 — Documents
PrefixSearchand the session-level full-text search shortcuts. - #5391 — The PostgreSQL setup docs described a Marten that no longer exists (stale PLV8 instructions, a non-functional image override, and an invented build matrix).
- #5395 — Enrolls
GuidOptimisticConcurrencyCompliancein the shared compliance suite. - #5370, #5371 — Takes Bobcat's shipped runner adapter and its interceptor opt-in.
Dependencies
- JasperFx 2.69.1
- Weasel 9.32.0
Known limitation
#5382's tenant-less registry answer reports ProcessedSequence and EventStoreSequence as 0 because nothing was read — which a caller cannot distinguish from a shard that has genuinely never run. That ambiguity is deliberate for now; #5383 tracks the database-scoped overloads that read real progression per database.
Cut as a minor on public API surface: #5400 adds ITenancy.TryFindDatabase, and #5397 changes DI registration.