Honor ListPrefix with ListUnfinished and fix listing cursor and page-size edge cases

Aperta
#184 1 commento 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@ffumero2003 ci sta già lavorando.

Dal 28/10/2026.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

bug

Context

  1. ListPrefix is ignored with ListUnfinished. The unfinished-file lister never sends namePrefix to b2_list_unfinished_large_files, so List(ctx, ListPrefix("app/tmp/"), ListUnfinished()) returns every unfinished large file in the bucket. A cleanup loop that cancels what it lists then cancels in-progress uploads under other prefixes. Writer.Resume also pages through the whole bucket.
  2. Version listing may stop early with a delimiter (needs confirmation against B2). Paging continues only when both nextFileName and nextFileId are set. With a delimiter the next entry can be a folder with no file ID; the Python SDK continues on nextFileName alone. If B2 returns a name without an ID there, blazer ends the listing with Err() == nil.
  3. ListPageSize default differs from its doc for file listings. The doc says 1000 (100 for unfinished large files), but file-name and file-version listings send maxFileCount: 0 (those request fields have no omitempty), leaving the page size to the server. B2 documents a default of 100 (its handling of an explicit 0 is not confirmed here); if it applies that default, a default listing makes up to ten times more calls than documented. The 1000 cap also prevents using B2's 10,000 maximum. Unfinished-file listings are not affected: that request already omits a zero count.
  4. ListKeys stops on an empty page that carries a cursor, the same case fixed for objects in Backblaze/blazer#70.
Current behavior

At a5e0d13:

  • b2/iterator.go:324-336: no prefix reaches the API and the next cursor drops it; internal/b2types/b2types.go:430-434: the request type has bucketId, startFileId, maxFileCount only; b2/writer.go:420: Writer.Resume lists with ListPrefix(w.name) and ListUnfinished().
  • b2/iterator.go:261-269: if name != "" && id != "" gates the next version page.
  • b2/iterator.go:100-104 and :214-221: a page size of 0 passes through; internal/b2types/b2types.go:342 and :355: maxFileCount without omitempty on the file-name and file-version requests (the unfinished request at :433 has omitempty); b2/sync/sync.go:178: the sync engine lists the destination with bucket.List(ctx, b2.ListPrefix(prefix)) and no page size, so it uses this default.
  • b2/key.go:149-151: if len(ks) == 0 { return nil, "", io.EOF } before checking next.
Expected behavior

Listings honor every option they accept, continue until the server reports no more entries, and use the documented page size.

Acceptance criteria

  • R1. List(ListPrefix(p), ListUnfinished()) returns only names under p, and the request carries namePrefix.
  • R2. A version page with nextFileName and no nextFileId continues.
  • R3. The default file-name and file-version iterators send the documented page size.
  • R4. ListKeys with an empty page and a cursor does not return io.EOF.
  • R5. A live check covers delimiter plus versions across a folder boundary.

In scope

Proposed change
  1. Add NamePrefix string (namePrefix,omitempty) to ListUnfinishedLargeFilesRequest, pass it through base, b2Bucket and beBucket, and keep it in the cursor. Until then, filter by prefix on the client.
  2. Continue version listings when nextFileName is set, sending startFileId only when present.
  3. For file-name and file-version listings, send the documented default page size (or fix the doc) and allow up to 10,000.
  4. In ListKeys, return io.EOF only when next is empty.

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 ./b2/... ./base
  • Assert literal wire fields/cursors and results for prefix-scoped unfinished listing, name-only version cursors, page-size defaults, and empty key pages with a continuation cursor.
  • Run the required live delimiter/version boundary check separately, recording credentials/environment requirements and actual output.
  • 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

Merged Backblaze/blazer#70 fixed early termination on empty pages for file listings. Open Backblaze/blazer#157 (resume unfinished large-file uploads in sync) needs to find the unfinished file for one name, so it depends on item 1.

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.