Skip to content

DeleteBucket: retired segments' space registrations are unenumerable; needs a space-scoped bulk release #76

Open

Description

@frrist

Problem

Deleting a bucket requires its Forge space to be empty: hilt's /s3/bucket/delete checks
SpaceEmpty (a /space/blob/list against sprue) and refuses while any registration remains.
Since #68, DeleteBucket releases the blobs its catalog segments registered — each shipped
segment's CAR and sharded-dag-index — by enumerating the bucket's segment rows and invoking
/space/blob/remove per digest.

That enumeration only covers registrations the rows still describe. Retention prunes segment
rows past the Retain window (default 6) after retiring their local CARs, and retiring is
local-only by design: the network copy is the durable read tier, so the CAR and index stay
registered in the space with no remaining record on ingot's side. Consequences:

  • A long-lived bucket with more than Retain shipped catalog segments cannot be fully
    released by ingot at deletion — DeleteBucket returns BucketNotEmpty even though the
    bucket holds no objects.
  • Registrations leaked by past best-effort release failures (releaseBlobs logs and moves on)
    are equally invisible to the enumeration.
  • Even with complete records, the per-digest /blob/remove loop is one RPC per blob and will
    not scale to old buckets.

Raised in review: #68 (comment)

Proposal

Replace per-blob enumeration with a space-scoped teardown at bucket deletion, on the
service side — either shape works:

  • sprue: a bulk /space/blob/remove (remove-all, or paginated remove-by-list) that
    deregisters every blob in the space and forwards the releases to the holding providers; or
  • hilt: /s3/bucket/delete tears the space down itself when it knows the bucket is being
    deleted (it already owns the space lifecycle and the SpaceEmpty check), instead of
    refusing on a non-empty space.

Either way ingot's DeleteBucket drops the enumerate-and-release pass (keeping the quiesce,
which is still needed so an in-flight ship cannot re-register after teardown), and a space
wipe also sweeps historic leaks that no local record describes.

Cross-repo: the mechanism lands in sprue or hilt; this issue tracks the ingot side and the
overall shape.

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions