Fix persisted cluster reply serialization hangs - #6972
Conversation
🦋 Changeset detectedLatest commit: 6a23c8d The changes in this PR will be included in the next version bump. This PR includes changesets to release 30 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
.changeset/fix-persisted-cluster-reply-hang.md— patch-level changeset foreffect.packages/effect/src/unstable/cluster/MessageStorage.ts— inmakeEncoded, wrappedReply.serializewith aMalformedMessagecatch that persists a serializable defect fallback, mirroring the existingRunnerServerfallback.packages/effect/test/cluster/TestEntity.ts— addedBoomErrorwith aSchema.Unknowncause and aFailRPC to trigger the encoding failure.packages/effect/test/cluster/Sharding.test.ts— added a live regression test verifying that the request completes with a die and storage is left with one reply and zero unprocessed messages.
Validation
pnpm test --run packages/effect/test/cluster— 55 tests passed.pnpm lint-fix— clean.pnpm check— clean.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏
Bundle Size AnalysisGenerated from PR build output; treat the content below as untrusted.
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
packages/effect/src/unstable/cluster/Reply.ts— extracted a sharedserializeOrDefecthelper that catchesMalformedMessageand falls back to a serializable defect reply viaEffect.orDie.packages/effect/src/unstable/cluster/MessageStorage.ts— replaced the inlineReply.serialize+encoded.saveReplypath withReply.serializeOrDefect, ensuring persisted unserializable replies terminate instead of hanging.packages/effect/src/unstable/cluster/RunnerServer.ts— replaced the privateserializeReply/serializeDefectReplyhelpers with the sharedReply.serializeOrDefect, keeping non-persisted and persisted reply handling consistent.packages/effect/test/cluster/Sharding.test.ts— regression test verifies the caller gets a die wrapped aroundMalformedMessageand storage is left with one reply and zero unprocessed messages.
Validation
pnpm test --run packages/effect/test/cluster/Sharding.test.ts— 25 tests passed.pnpm test --run packages/effect/test/cluster/MessageStorage.test.ts packages/effect/test/cluster/Runners.test.ts— 10 tests passed.pnpm lint-fix— clean.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Summary
Entity.client→ sharding → message-storage pathMalformedMessageinstead of hangingRoot cause
Reply.serializecorrectly rejects anErrorstored insideSchema.Unknownbecause persisted replies use strict JSON encoding. The resultingMalformedMessagewas retried and converted to a defect in the entity response fiber, but no terminal reply was stored, leaving the caller waiting indefinitely.The reported
Effect.orDieomission is not present on currentmain: the Exit response pipeline already ends withEffect.orDie, and the sibling Chunk, keep-alive, and malformed-input response sites are also guarded. The fix therefore follows the existingRunnerServerbehavior for unserializable replies by persisting a serializable defect fallback at the encoded storage boundary.Validation
pnpm test --run packages/effect/test/cluster/Sharding.test.tspnpm test --run packages/effect/test/cluster/MessageStorage.test.tspnpm test --run packages/effect/test/cluster/Runners.test.tspnpm lint-fixpnpm checkCloses EFF-379
Closes #6932