Fix README and example patterns that commit truncated uploads or overwrite local files on failure

Aperta
#187 0 commenti 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@ffumero2003 ci sta già lavorando.

Dal 8/11/2026.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
45/100
Tipo di issue
Documentazione
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
go

Direzione di ricerca

Start with the upload and download snippets in README.md, then read b2/writer.go and examples/simple/simple.go for the failure behavior described. Update the examples, memory guidance, and AuthToken prefix and credential notes; the proposed example_test.go examples should compile with go vet ./.... Done when the acceptance criteria pass, including failed uploads leaving no object and failed downloads preserving the existing file.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

documentation

Context

The README's upload examples call w.Close() on the io.Copy error path. Writer.Close finishes the upload with whatever was written, so when the source is not seekable (a pipe, a network stream, an io.Reader adapter), a source read error stores a truncated object as the newest version and Close returns nil. The README examples read from an *os.File, which takes the seekable path, but the pattern is what users copy for other readers. The download examples truncate the local destination before the first byte arrives, so a mistyped object name empties the local file. The README also omits memory use and uses an AuthToken prefix ("photos") that also matches photos-private/....

Current behavior

At a5e0d13:

  • README.md lines 116-122 and 141-147: if _, err := io.Copy(w, f); err != nil { w.Close(); return err }.
  • b2/writer.go:649-652: for a non-seekable source, ReadFrom runs a plain copy (b2/reader.go:378-405) and returns the source error without recording it on the writer.
  • b2/writer.go:717-773: Close has no abort path. Cancelling the NewWriter context before Close is the only way to discard.
  • Reproduced at a5e0d13 with Go 1.27.3, the README snippets as written and the x/b2sim in-process simulator: a non-seekable source returning 1000 bytes then an error gives io.Copy err=source read failed; w.Close()=nil, and the stored object has 1000 bytes. With ChunkSize 5e6 and a source failing after 12e6 bytes (large-file path), Close also returns nil and 12000000 bytes are stored.
  • README.md lines 159-173 and examples/simple/simple.go:84-106: os.Create(dst) runs before the lazy reader (b2/b2.go:763-796) makes its first request. Downloading a missing object over an existing 19-byte file returned 404: file not found and left the file empty.
  • examples/simple/simple.go:51-111: every error path prints to stdout and returns from main; a failed upload copy returns without cancelling, leaving an unfinished large file.
  • README.md lines 126-127 and 151-152 describe ChunkSize and ConcurrentUploads but not that the in-memory buffer is one ChunkSize per concurrent upload (about 1 GB for 10 uploads by default); neither does the ConcurrentUploads doc (b2/writer.go:44).
  • README.md line 231: bucket.AuthToken(ctx, "photos", time.Hour); lines 234-235 do not say the token is a bearer credential.
Expected behavior

Copy-pasted examples never store partial data, never destroy local files on failure, and describe limits and token scope correctly.

Acceptance criteria

  • R1. With the in-memory backend, the documented upload pattern leaves no new object when a non-seekable source fails mid-copy.
  • R2. The documented download pattern leaves an existing destination file untouched when the object is missing.
  • R3. examples/simple exits non-zero for a missing object.
  • R4. The README states the memory formula; AuthToken uses a slash-terminated prefix.
  • R5. go vet ./... compiles Example functions for upload, download, list and AuthToken.

In scope

Proposed change
  • Cancel the writer context before Close on copy errors in both upload snippets, and state in the Writer/Close docs that Close commits what was written. Consider a Writer.Abort or CloseWithError.
  • Download to a temp file in the destination directory and os.Rename it after success.
  • Make examples/simple write errors to stderr, exit non-zero, and cancel on copy failure.
  • Add the memory formula with a pointer to UseFileBuffer.
  • Use "photos/" in the AuthToken example, explain that the prefix is a plain string prefix, and note that the token grants read access to anyone who holds it.
  • Move snippets into example_test.go so they are compiled and shown on pkg.go.dev.

Out of scope

  • Unrelated work outside the components and behavior described in In scope.

Verification

Run the repository regression checks with live credentials unset:

unset B2_APPLICATION_KEY_ID B2_APPLICATION_KEY B2_ACCOUNT_ID B2_ACCOUNT_KEY
go build ./...
go vet ./...
go test -race -count=1 ./...
  • Use the stated failing non-seekable source and missing-download cases. Verify that the documented upload stores no new truncated object and that the local destination remains unchanged.
  • Record the example CLI's nonzero exit for a missing object and compile the examples through the originally requested go vet ./....
  • Check the memory formula, slash-terminated token prefix, and bearer-token explanation.
  • Expected result: the checks above succeed and the observable outcomes in Acceptance criteria are demonstrated. If a check cannot run, report Could not run because: ...; if it starts but fails, report Could not complete because: .... A skipped check is not a pass.

Links

Backblaze/blazer#168 (merged; refreshed the README and corrected the part-size text, but kept these patterns)

Lingua principale
Go
Stelle
66
Fork
18
Merge medio
1g 10h
PR unite (30g)
132

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di Backblaze/blazer

Tutte le issue di Backblaze/blazer

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.