Skip to content

Adopt JasperFx.Events 1.35.0: fan-out enrichment + composite cache fix (#4329)#4338

Merged
jeremydmiller merged 1 commit intomasterfrom
4329-multi-entity-enrichment
May 7, 2026
Merged

Adopt JasperFx.Events 1.35.0: fan-out enrichment + composite cache fix (#4329)#4338
jeremydmiller merged 1 commit intomasterfrom
4329-multi-entity-enrichment

Conversation

@jeremydmiller
Copy link
Copy Markdown
Member

Summary

Closes out the followup ask in #4329. Two JasperFx.Events 1.35.0 changes flow into Marten via this PR, plus a Marten-side integration test and the docs that go with them.

Two upstream fixes pulled in via the package bump

  1. Composite-projection cache eviction fix (JasperFx/jasperfx#206) — per-projection caches are no longer compacted between stages of a composite. Earlier, with a small `CacheLimitPerTenant`, end-of-stage-1 compaction evicted entities that downstream stages were about to look up via `EnrichWith().AddReferences()` or `TryFindUpstreamCache<TId, T>`. Evicted ids fell through to `storage.LoadManyAsync`, which can't see the upstream's queued in-flight writes — silently dropping them. `CacheLimitPerTenant` is now a memory tunable again, not a correctness lever for downstream lookups.

  2. `ForEntityIds` for fan-out enrichment (JasperFx/jasperfx#208) — a first-class declarative variant of `ForEntityId` for events that reference several entities of the same type, e.g. `OrderPlacedWithLineItems` carrying a list of `ProductId`s. Each resolved id materializes as one `References` synthetic event, so `Evolve` reads them through the same case arm as the 1-to-1 case.

Marten-side changes in this PR

  • `Directory.Packages.props`: `JasperFx.Events` `1.34.0` → `1.35.0`.
  • New `Bug_4329_fan_out_and_cache_limit` integration test with two facts:
    • `fan_out_one_event_to_many_upstream_references` — a single `OrderPlacedWithLineItems` event references 5 upstream `Product`s; `OrderSummaryProjection.EnrichEventsAsync` uses `ForEntityIds` and the resulting `OrderSummary` has 5 line items.
    • `cache_limit_one_does_not_break_downstream_lookups` — same shape with 20 products and `ProductProjection.CacheLimitPerTenant = 1`. Without the JasperFx.Events 1.35.0 fix this would silently drop 19 of the 20 lookups; with the fix, all 20 resolve.
  • Docs:
    • `composite.md` cross-stage section now lists `ForEntityIds` alongside `ForEntityId`, and the closing `TryFindUpstreamCache` paragraph drops the cache-eviction caveat. New `:::tip` calls out that 1.35.0 makes `CacheLimitPerTenant` a memory tunable again.
    • `enrichment.md` gains a "Fan-out enrichment with `ForEntityIds`" section, sourced from `#region sample_for_entity_ids_fan_out` on the new test, with an inline `Evolve` example showing how `References` fires once per resolved id.

Test plan

  • All 8 `DaemonTests/Composites/*` tests pass on net10.0 (the existing 6 plus the 2 new).
  • The cache-limit test specifically verifies the regression scenario from the diagnosis comment on #4329 — without 1.35.0 it fails the same way (`OrderSummary.Lines.Count == 1` instead of 20); with 1.35.0 it passes.

Polecat parity

Tracked in JasperFx/polecat#41. Polecat's composite projection support is built on the same JasperFx.Events foundations, so it inherits both fixes once it bumps the package; the issue covers the bump, an integration test mirror, and the docs.

🤖 Generated with Claude Code

JasperFx.Events 1.35.0 ships two changes that close out the usability gap
@xander-abn surfaced in #4329:

1. Composite-projection cache eviction fix (JasperFx/jasperfx#206) —
   AppointmentByExternalIdentifier (and similar EnrichWith<UpstreamDoc>
   chains) no longer drop downstream lookups when the upstream's
   CacheLimitPerTenant is small relative to per-batch fan-out.

2. ForEntityIds (JasperFx/jasperfx#208) — first-class declarative shape for
   1-event-to-N-entities enrichment.

This commit:

- Bumps JasperFx.Events 1.34.0 → 1.35.0 in Directory.Packages.props.
- Adds Bug_4329_fan_out_and_cache_limit with two facts: a fan-out scenario
  using ForEntityIds (one OrderPlacedWithLineItems event referencing 5
  upstream Product documents), and a cache-eviction regression that
  intentionally sets ProductProjection.CacheLimitPerTenant = 1 and verifies
  20 distinct upstream lookups all resolve to the in-flight cache.
- Wires the new patterns into composite.md and enrichment.md, removes the
  now-stale "cache-limit is load-bearing for correctness" caveat, and
  adds a "Fan-out enrichment with ForEntityIds" section sourced from
  #region sample_for_entity_ids_fan_out in the new test.

Refs #4329, JasperFx/jasperfx#206, JasperFx/jasperfx#208.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant