Relationships
#1729 localHasAllRemoteEntries() permanently blocks sidecar update on partial caches
Opened by magistr · 8/19/2026
Summary
When using shard-first (v2) index, the push no-writeback path gates writing commitSeq to the sidecar on localHasAllRemoteEntries() (s3_cache_sync.ts:2358-2372). This method stats all index entries against the local cache and returns false if any file is missing or has a different size.
In a multi-writer setup (e.g. swamp serve on Unraid pushes data that a Mac workstation hasn't fully hydrated), this check always returns false. Result: commitSeq is never written to the sidecar, and the fast-path short-circuit is permanently dead.
Impact
Every CLI command takes the full slow path (~4.5s baseline instead of <1s). Measured on a repo with 129k index entries / 50MB index file.
Reproduction
- Set up S3 datastore with shard-first index (v2)
- Run workflows from
swamp serve— they push data to S3 - On a different machine (Mac workstation), run any command
- Observe
.datastore-sync-state.jsonnever getscommitSeqpopulated - Every command takes ~4-4.5s instead of fast-path ~1s
Suggested fix
For the push no-writeback path (pushed == 0 && deleted == 0), record commitSeq in the sidecar without the localHasAllRemoteEntries() gate. The push path's job is "did I push everything dirty?" — not "does my cache have everything the remote has". Cache completeness is the pull path's responsibility.
The localHasAllRemoteEntries() check should only gate marking the pull sidecar as clean (preventing the pull fast-path from skipping unfetched files).
References
s3_cache_sync.ts:2358-2372(v2 no-writeback branch)s3_cache_sync.ts:2309-2317(v2 writeback branch — same gate)s3_cache_sync.ts:2967-2984(localHasAllRemoteEntriesimpl)
Upstream repository: https://github.com/systeminit/swamp-extensions
Environment
- Extension:
@swamp/s3-datastore@2026.08.12.1 - swamp:
20260819.011806.0-sha.a9c7ee9a - OS:
darwin(x86_64) - Deno:
2.8.3 - Shell:
/bin/zsh
Closed
No activity in this phase yet.
stack72 commented 8/27/2026, 4:48:33 PM
Hey @magistr, thanks for the detailed write-up. I've reviewed the code and while the observation about the gate is directionally correct, the suggested fix would introduce data loss.
The localHasAllRemoteEntries() gate on the push no-writeback path exists because the sidecar's commitSeq feeds tryCommitSeqFastPath, which is the pull fast path. If we record commitSeq without verifying local completeness, the next pullChanged call matches commitSeq, returns 0, and skips downloading files the machine doesn't have. That's the exact scenario the gate prevents.
Also noting the line references are off by ~15-20 lines from what's in the current codebase (e.g., the no-writeback branch is at line 2376-2390, not 2358-2372), which suggests this was filed from a read of the source rather than from hitting the issue in practice.
Closing this — the gate is intentional and removing it would be unsafe.
Sign in to post a ripple.