Repository navigation
JasperFx 2.69.2
Two fixes and a documentation correction.
#832 — generated statement order moved between runs
Thanks to @AllainPL for the diagnosis, the provenance and a deterministic repro.
MethodFrameArranger.compileFrames step 3 enumerated DependencyGatherer.Dependencies, an ImHashMap keyed by Frame. Frame does not override GetHashCode, so that walk followed identity hash codes and differed between two arrangements of the same logical method — and step 4's topological sort preserves the relative order of independent frames, so the emitted body carried the variation. #196 fixed exactly this for DependencyGatherer.Variables, which is why constructor parameters and fields have been stable and the statements inside the method were not.
Measured on a real application with committed generated code, running codegen write twice in the same environment: 15 of 60 files differed at 1.24.1, 6 of 60 still differed at 1.31.0 (the first release carrying #196). What was left moving is statement order. This also closes out JasperFx/wolverine#3059, which reported the same drift as a macOS-vs-Linux difference and guessed at the cause without a repro.
The fix walks frames and indexes the cache rather than enumerating the cache. The cache's keys are exactly the frames passed in — DependencyGatherer's constructor fills one entry per frame and nothing adds a key before step 3 — so the set gathered is unchanged and only the order becomes deterministic.
⚠️ Expect a one-time diff. If you have generated code committed, regenerating on 2.69.2 may reorder statements within a method once as they settle into a stable order. That is this fix landing, not a semantic change. Subsequent regenerations are byte-identical — which is the point: a drift check in CI, a code review, or a reproducible build can now tell a real change from hash-order noise.
#831 — a stale claim on SupportsMultipleDatabases
The remarks said "Fisher is legitimately false — one file, one database." Fisher has had database-per-tenant since fisher#47 and runtime tenants since fisher#58, and both arms of MultiDatabaseExplorerCompliance are green there. Replaced with the store-neutral condition, plus the part that makes it matter: a Fisher tenant is a file, so this is the one suite in the set whose precondition is nearly free there and expensive on the other two — the opposite of what the old sentence implied.
Docs
WaitForNonStaleProjectionDataAsync's contract is now stated on the fixture seam: wait on every configured shard, not every shard that has reported. An implementation that gates on the rows it finds is satisfied by a store where one projection reached the head and another never ran — the wait returns and the next read sees a document that was never written. polecat#602 shipped that defect.