Polecat parity port from Wolverine.Marten + Polecat 2.1.0 bump#2598
Merged
jeremydmiller merged 3 commits intomainfrom Apr 27, 2026
Merged
Polecat parity port from Wolverine.Marten + Polecat 2.1.0 bump#2598jeremydmiller merged 3 commits intomainfrom
jeremydmiller merged 3 commits intomainfrom
Conversation
…cat 1.6.1 → 2.1.0 Brings Wolverine.Polecat to parity with several improvements that landed in Wolverine.Marten over the past few weeks. All ports preserve existing public surface — additions only. ## Changes **Polecat NuGet 1.6.1 → 2.1.0** (Directory.Packages.props) **Wolverine.Polecat** - WriteAggregateAttribute.Modify() now respects an explicitly set ValueSource (e.g. via FromMethod/FromRoute/FromHeader/FromClaim) when resolving the aggregate id, falling back to the existing FindIdentity() logic. Mirrors Wolverine.Marten#2451 fix. - PolecatOps.StoreObjects(...) for storing mixed document types as a single side effect. Polecat's IDocumentOperations doesn't expose StoreObjects, so the operation dispatches each document by runtime type to the generic Store<T>(document) method via cached MethodInfo. - New IDocumentsOp interface mirroring Marten's IDocumentsOp; DocumentsOp now implements it. - Fluent .With(document) / .With(documents[]) on StoreManyDocs<T> and StoreObjects for incremental document accumulation. - Tenant-scoped StoreObjects(string tenantId, params object[]) overload. - New Codegen/TagAggregateOtelFrame injected by AggregateHandling.Apply() to emit wolverine.stream.id and wolverine.stream.type Activity tags for every Polecat aggregate handler workflow. Mirrors Wolverine.Marten#2470 with the value-type aggregate id codegen fix from 5.30.0. **PolecatTests** - New PolecatOps_store.cs covering StoreMany/.With/StoreObjects/.With + tenant-scoped overload + IDocumentsOp surface. - aggregate_handler_workflow gains generates_wolverine_stream_id_otel_tag and generates_wolverine_stream_type_otel_tag codegen assertions. **Docs** - docs/guide/durability/polecat/operations.md gains "Storing Multiple Documents" and "Tenant-Scoped Operations" sections mirroring the Marten operations docs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Polecat 2.0 changed the default JSON storage to use SQL Server 2025's
native `json` column type (StoreOptions.UseNativeJsonType defaults to
true). The previous Azure SQL Edge image only emulates SQL Server 2022,
which fails Polecat schema migrations with:
Microsoft.Data.SqlClient.SqlException : Column, parameter, or
variable #6: Cannot find data type json.
This was causing every PolecatTests integration test to fail in CI.
Switch the shared docker-compose sqlserver service to the official
mcr.microsoft.com/mssql/server:2025-latest image (matches Polecat's own
docker-compose recommendation) and add MSSQL_SA_PASSWORD alongside the
legacy SA_PASSWORD env var for forward compatibility. Existing
Wolverine.SqlServer / RDBMS tests continue to work — SQL Server 2025
is backward-compatible at the schema level.
Documents the Apple Silicon caveat in a comment: ARM Mac users may want
to override locally via docker-compose.override.yml + UseNativeJsonType
= false on test fixtures, since SQL Server 2025 under Rosetta can be
flaky on memory-constrained machines.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The two `generates_wolverine_stream_*_otel_tag` tests on the Polecat port were failing in CI with `NullReferenceException` from `Shouldly.StringHelpers.Clip` because `chain.SourceCode` was null — the chain hadn't been compiled yet. The Marten originals these tests were ported from call `theHost.GetRuntime().Handlers.HandlerFor<RaiseABC>()` first to trigger compilation, then `ChainFor<RaiseABC>()` to inspect the resulting chain. That setup line was dropped during the port. Restore it. Companion `automatically_adding_stream_id_to_the_audit_members` test (which was passing) followed the same pattern incidentally because it accesses `chain.AuditedMembers` which triggers compilation as a side effect. The SQL Server image is already on `mssql/server:2025-latest` (commit 1e904ff on this branch), so the native JSON type Polecat 2.x emits is available. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jeremydmiller
added a commit
that referenced
this pull request
Apr 27, 2026
Release v5.33.0 includes: - Fix #2602: leader split-brain via stale Postgres advisory lock (#2607) - Port Polecat 2.x event store integration from Marten (#2598) - Fix #2571: preserve context fields on scheduled-send wrap/unwrap (#2605) - Add launchSettings.json to sample projects (#2600) - gRPC: middleware weaving, validate convention, user exception mapping, bidirectional streaming, code-first codegen, new samples (#2565) - Move non-sticky-handlers guard inside the compile lock (#2556) - Allow RabbitMQ exchanges to be declared passive (#2574) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Apr 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings Wolverine.Polecat to parity with several improvements that landed in Wolverine.Marten over the past few weeks. All ports are additive — no existing public surface changes.
Directory.Packages.propsWriteAggregateValueSourcerespect fix (parallel of WriteAggregate does not supportFromMethodstatic ID resolution #2451)PolecatOps.StoreObjects+IDocumentsOpinterface + fluent.With()builders (parallel of Add MartenOps.StoreObjects #1171 / 657d092 from Marten side)TagAggregateOtelFrame(parallel of Tag OTEL spans with saga ID and aggregate stream ID for saga and aggregate handler workflows #2470 + the 5.30.0 value-type aggregate-id codegen fix)Why this port
The Marten side has been the canonical reference and has accumulated several quality-of-life additions that Polecat users would benefit from. Keeping them in lockstep keeps the mental model identical for users switching between or running both.
Implementation notes
StoreObjectson Polecat: Polecat 2.1.0'sIDocumentOperationsdoes not expose aStoreObjects(IEnumerable<object>)method like Marten does. The port dispatches each document to the genericStore<T>(document)by runtime type using a cachedMethodInfoper type. This produces the same end-state semantics as Marten'sStoreObjects.TagAggregateOtelFrame: Direct port — usesActivity.Current?.SetTag(...)so it's a no-op when there's no OpenTelemetry consumer subscribed.WriteAggregateAttribute.Modify: Pre-checksValueSource != ValueSource.InputMember && ArgumentName.IsNotEmpty()and usestryFindIdentityVariable()(from the base class) before falling back to the existingFindIdentity()logic. Identical to the Marten patch.Test plan
dotnet build src/Persistence/Wolverine.Polecat/Wolverine.Polecat.csproj— clean (0 errors)dotnet build src/Persistence/PolecatTests/PolecatTests.csproj— cleanPolecatOps_storeunit tests pass locally (4/4)automatically_adding_stream_id_to_the_audit_membersfailure (Cannot find data type json) — unrelated to this PR.🤖 Generated with Claude Code