Skip to content

Polecat 5.18.0

Choose a tag to compare

@jeremydmiller jeremydmiller released this 18 Aug 00:42
· 2 commits to main since this release
21f53cb

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 implementation

Polecat'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. TryTake removes 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 FetchForWriting handed 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