fix(nwsync): close the review findings on the framing fix and verify
ci / ci (pull_request) Successful in 3m38s
ci / ci (pull_request) Successful in 3m38s
- compressBlob now asserts its own output declares a content size, instead of trusting that the only way to lose the field is the one #86 found. An encoder upgrade that finds another way would otherwise republish the same undecodable blob in silence, and a blob is skipped by every later emit once written. - inspectBlob asserts the frame whenever one is present, rather than only when the payload is non-empty. - dirSink stats instead of reading when not verifying. Reading every existing blob back on the default path was a plain regression, and it contradicted the documented promise that verifying is a repair pass, not the default. - The manifest sha1 is now checked as hex before it is interpolated into a URL path, rather than only measured. - One blobKey rule for where a blob lives, replacing three copies of the fanout-path expression. - Renamed frameSizeThreshold to oneByteContentSizeCeiling, which says whose threshold it is. - The read-back in zoneSink reads the storage API on purpose; said so, and corrected a comment that claimed a failed read-back re-uploads when it aborts. - Tests derive their expected blob counts from the run instead of hard-coding fixture arithmetic, and the size-mismatch category has a test. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+14
-5
@@ -45,10 +45,14 @@ type dirSink struct{ root string }
|
||||
|
||||
func (s dirSink) putBlob(sha1Hex string, verify bool, body func() []byte) (int64, error) {
|
||||
blob := blobPath(s.root, sha1Hex)
|
||||
if stored, err := os.ReadFile(blob); err == nil {
|
||||
if !verify || blobMatchesName(stored, sha1Hex) == nil {
|
||||
if !verify {
|
||||
// Stat, not read: the common path must not pay to open every blob that
|
||||
// is already there.
|
||||
if _, err := os.Stat(blob); err == nil {
|
||||
return 0, nil
|
||||
}
|
||||
} else if stored, err := os.ReadFile(blob); err == nil && blobMatchesName(stored, sha1Hex) == nil {
|
||||
return 0, nil
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(blob), 0o755); err != nil {
|
||||
return 0, fmt.Errorf("create blob directory: %w", err)
|
||||
@@ -100,7 +104,7 @@ type zoneSink struct {
|
||||
}
|
||||
|
||||
func (s zoneSink) putBlob(sha1Hex string, verify bool, body func() []byte) (int64, error) {
|
||||
key := path.Join("data", "sha1", sha1Hex[0:2], sha1Hex[2:4], sha1Hex)
|
||||
key := blobKey(sha1Hex)
|
||||
// A throttled probe must never be read as "missing, re-upload" or as
|
||||
// "present, skip", so only a confirmed Present skips the upload.
|
||||
state, _, err := s.store.ProbeKey(s.ctx, key)
|
||||
@@ -112,8 +116,13 @@ func (s zoneSink) putBlob(sha1Hex string, verify bool, body func() []byte) (int6
|
||||
return 0, nil
|
||||
}
|
||||
// The probe only proved the object exists. Read it back and hold it to
|
||||
// its own name; a failure here means re-upload, not abort, because
|
||||
// repairing what is there is the whole point of verifying.
|
||||
// its own name.
|
||||
//
|
||||
// This reads the storage API rather than the pull zone: emit holds the
|
||||
// write credential, and a repair decision has to be made against the
|
||||
// copy it is about to overwrite, not against an edge cache of it. A
|
||||
// read that fails outright is a fault, not a verdict — treating it as
|
||||
// "bad, re-upload" would turn a throttled zone into a full backfill.
|
||||
stored, err := s.store.GetKey(s.ctx, key)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("read back blob %s: %w", sha1Hex, err)
|
||||
|
||||
Reference in New Issue
Block a user