Polecat 5.18.0
Clears the whole open tracker on JasperFx 2.51.0. Three issues, all additive — nothing in this release is a breaking change.
IAggregateWriteCache in FetchForWriting (#478, jasperfx#674)
An opt-in, per-aggregate-type second-level cache of aggregate snapshots, shared with Marten and Fisher through JasperFx.Events.
opts.Events.CacheAggregatesForWriting<Order>(); // off for every type by default
opts.Events.AggregateWriteCaching.SizeLimit = 5000;
opts.Events.AggregateWriteCaching.Cache = myCache; // or supply your own implementationPolecat's FetchForWriting live-aggregates rather than loading a stored snapshot, so what a cache hit removes here is the re-read of every event in the stream from version 1 — it collapses to reading only the events committed after the cached baseline.
The cached snapshot is a baseline and nothing more. The stream version is still read on every call, in the same statement it always was, and the optimistic concurrency assertion on append is untouched. A stale entry costs a larger delta query — never a wrong aggregate, and never a suppressed concurrency failure. Two cases refuse to trust a baseline and refetch from version 1: an entry ahead of the stream (a restore or a rollback), and a stream whose events were archived out from under it.
Two implementation details are worth knowing if you write your own IAggregateWriteCache:
- Entries are published on commit, not at fetch.
TryTakeremoves the entry atomically, so exactly one caller can hold an instance; publishing early would hand out an instance the fetching session still holds. A consequence: a fetch that appends nothing never warms the cache. - An entry claims the stream version read at the top of the fetch, not the version the commit landed on — Polecat's inline projection writes its own document rather than mutating the instance
FetchForWritinghanded out, so the instance never advances past its build version.
Held to AggregateWriteCacheCompliance (14 facts) plus Polecat-local tests for both decisions above.
IDocumentSessionOperations.PendingStreams (#477, jasperfx#673)
The StreamActions a session has queued but not yet committed, now readable through the shared document contract — for a listener or a pre-commit hook deciding something from the events a session is about to write, without naming a store.
Polecat already had this collection on PendingChanges.Streams and the payload type was already the shared StreamAction, so this closes a naming gap rather than a capability gap; a Polecat caller can keep reading PendingChanges.Streams directly. Held to PendingStreamActionsCompliance (9 facts).
Document compliance honors the declared stream identity (#479, jasperfx#672)
PolecatDocumentComplianceFixture replays DocumentComplianceConfig.StreamIdentity instead of inferring string identity from a non-empty config.EventTypes. Test-infrastructure only — no shipped behavior changes. The old inference was correct when written and would have gone silently wrong the moment a document suite named an event type without wanting string identity.
Dependencies
JasperFx, JasperFx.Events, JasperFx.Events.ComplianceTests, JasperFx.SourceGenerator and JasperFx.Events.SourceGenerator move 2.50.0 → 2.51.0 in lockstep (#480). JasperFx.RuntimeCompiler stays on 5.0.0 and Weasel stays on 9.24.0.
Upgrading
Nothing to do. The aggregate write cache is off for every type until you enroll one, PendingStreams replaces a contract member that previously threw, and no schema changes.
Full suite: 2198 passed, 0 failed, 3 skipped on net10.0, plus the default and edge CI matrices.
Full changelog: v5.17.0...v5.18.0