fix: sync getBulk correctly decodes mixed hashed and plain keys#195
fix: sync getBulk correctly decodes mixed hashed and plain keys#195bihaoxwork wants to merge 4 commits into
Conversation
Refactor getBulkData to split hashed vs plain keys and route each set through the appropriate transcoder path, fixing incorrect decoding when a single bulk request contains both hashed and unhashed keys. Re-enable the previously disabled getBulk test path in EVCacheTestDI. Co-authored-by: Bihao Xu <bxu@netflix.com>
Code ReviewSummaryRefactors the synchronous Approval RecommendationComment — no blocking issues. The mixed-key decode, the transcoder-fallback port from #184, and the chunked+hashed read path were all independently verified correct. Consider the null-guard suggestion and the test/observability considerations at your discretion. Issues FoundSuggestions
Considerations
Pre-existing IssuesExists on unchanged code (introduced in #181 for the async path), now also reachable from the sync path. Not reachable through normal flow since memcached only returns requested keys — listed for awareness.
Questions for the AuthorNone — the chunking-routing design and the chunked+hashed read path were verified correct (chunks are stored under Notes
Generated with pr-review-plugin (Claude + Codex) |
Code ReviewSummaryRe-review of the delta since the last review (1 new commit, no new discussion), now cross-checked against the team's EVCache review guidelines. The new commit Approval RecommendationComment — the NPE fix is verified correct and the collision-drop change is on-standard. Items below are non-blocking. Issues FoundConsiderations
Documentation Suggestions
Pre-existing IssuesThese exist on unchanged code and predate this commit; listed for awareness only.
Questions for the AuthorNone — the open questions about the drop-vs-null intent are covered by the Documentation Suggestion above and have no functional impact (downstream normalization). Notes
Generated with pr-review-plugin (Claude + Codex) |
Code ReviewSummaryThird (delta) review. The delta since the last review is a single commit ( Approval RecommendationApprove — the mixed-key decode fix has been independently verified correct across three reviews, the chunked + hashed read path is now structurally asserted (plain path) and round-trip-verified (hashed path), and the previously-flagged NPE and observability gaps are closed. The single consideration below is trivial and non-blocking. Issues FoundConsiderations
Questions for the AuthorNone. Notes
Generated with pr-review-plugin (Claude + Codex) |
242cce8 to
79d1d73
Compare
| } | ||
| } | ||
|
|
||
| final Map<String, CachedData> dataMap = evcacheMemcachedClient.asyncGetBulk(allKeys, chunkingTranscoder, null, chunkingNodeValidator(Call.BULK)) |
There was a problem hiding this comment.
Still trying to understand what assembleChunks does, so just curious should we still be using this deprecated version of asyncGetBulk here?
There was a problem hiding this comment.
IIUC these are the keys that we encoded using chunkingTranscoder? is this a third layer of encoding/decoding on top of the valueTranscoder and envelopeTranscoder?
There was a problem hiding this comment.
nit: If it's correct to use this single transcoder version method, we can either
- remove the deprecated annotation in that method and enhance its comment to justify its use case or
- use the double transcoder version and pass null as the second transcoder.
There was a problem hiding this comment.
Good questions, let me address all three together since they're related.
On the "third layer of encoding" (and what ChunkTranscoder is): ChunkTranscoder isn't really an encode/decode layer. It's an identity transcoder, decode and encode both just return the input unchanged:
public CachedData decode(CachedData d) { return d; }
public CachedData encode(CachedData o) { return o; }Its only job is to avoid deserializing so we can pull the raw chunk bytes off the wire and reassemble them. So there's no third codec. The actual decoding is still just the two layers you mentioned, done in decodeForKey after reassembly: envelopeTranscoder to unwrap the EVCacheValue, then valueTranscoder for the payload.
On using the deprecated asyncGetBulk here: because of the above, at this point we're only reading chunk keys (key_00, key_NN) as raw bytes, every key takes the exact same single-step read, there's no plain-vs-hashed transcoder distinction at the chunk layer. The deprecation note only warns against using this overload when you need the memcached layer to do the 2-step hashed decode, which doesn't apply to chunk reads. So functionally it's the right method here. I think we can remove deprecated annotation.
I will use the double transcoder version also add some comments back assembleChunks
Summary
decoding when a single sync getBulk request contains both hashed and unhashed keys.
Test