Skip to content

tracking: support atomic conditional delete across services #8157

Description

@Xuanwo

Feature Description

Track service implementations of atomic conditional delete: delete an object only when the caller-provided revision still matches the current object.

Capability::delete_with_if_match must be advertised only when the service preserves OpDelete::if_match in one-shot deletion and every enabled native batch path. A mismatched condition must be reported as a conditional failure and must leave the object intact.

This follows the S3 and Azure work in #7090, #8141, and #8142.

Problem and Solution

Lease release, orphan cleanup, and similar coordination paths require an atomic compare-and-delete operation. A client-side HEAD followed by unconditional DELETE has a time-of-check/time-of-use race and does not satisfy this contract.

The current repository inventory found the following implementation candidates.

ETag / object-SHA conditions that fit delete_with_if_match

  • S3: finish the batch correctness work in feat(services): support conditional delete for Azure services #8142. Native batch deletion must preserve each input condition and return per-object condition failures.
  • Azure Blob Storage and Azure Data Lake Storage Gen2: finish feat(services): support conditional delete for Azure services #8142. Azure Blob batch subrequests must preserve If-Match independently.
  • GitHub: pass OpDelete::if_match as the required blob sha in the Delete a file request. OpenDAL already exposes the blob SHA as the file ETag; the delete path currently performs its own lookup instead of using the caller's value.
  • OneDrive: send If-Match to Delete DriveItem. Microsoft Graph documents 412 Precondition Failed and guarantees that the item is not deleted when the tag does not match.
  • WebDAV: send the standard HTTP If-Match header on DELETE. RFC 9110 defines this for state-changing methods, including DELETE, and RFC 4918 recommends entity-tag conditions for WebDAV modifications. Verify the behavior against representative WebDAV servers before advertising the capability.

Atomic revision conditions that do not fit the current ETag field

These providers have an atomic primitive, but their condition is not the object's ETag. They need a typed revision/generation precondition instead of overloading if_match.

  • Google Cloud Storage: Objects: delete supports ifGenerationMatch. OpenDAL already exposes the generation as Metadata::version; the JSON API does not expose an ETag If-Match parameter for delete.
  • Dropbox: files/delete_v2 and every files/delete_batch entry accept parent_rev, which deletes a file only when the latest revision matches. OpenDAL exposes Dropbox rev as Metadata::version, while its ETag is the content hash.
  • Hugging Face git repositories: commit APIs accept parent_commit, which protects the repository head rather than one object's ETag. Define whether a repository-wide revision condition belongs in the common delete contract before implementing it.

No documented atomic ETag delete path

The current provider API references expose unconditional deletion or version selection, but no per-object ETag condition:

  • Azure Files
  • Alibaba Cloud OSS
  • Tencent COS
  • Huawei OBS
  • Volcengine TOS
  • OpenStack Swift, including bulk delete
  • Cloudflare Workers KV

Do not advertise delete_with_if_match for these services unless provider documentation and a live service test demonstrate an atomic condition. Version selection is a separate capability and must not be reported as ETag matching.

Other services that expose delete but do not return a stable object tag or revision remain out of scope until they gain a caller-observable comparison token. GooseFS and lakeFS need separate provider-level verification because their current OpenDAL ETags are identifiers or checksums, not documented delete preconditions.

Implementation Requirements

Each service implementation should include behavior coverage that verifies:

  • matching conditions delete the object;
  • mismatching conditions return ConditionNotMatch and leave the object intact;
  • native batch deletion preserves conditions independently for every entry;
  • mixed batch results report successful and failed entries correctly;
  • the service advertises delete_with_if_match only after the actual backend passes the behavior test.

Service-specific pull requests should link this issue and update the checklist. Requests containing if_match must not fall back to HEAD plus unconditional DELETE. A service without a native atomic primitive must keep the capability disabled.

Additional Context

This inventory was prepared with material AI assistance and reviewed by the submitter. Provider behavior not covered by existing live CI remains an explicit unknown and must be reproduced against the actual service before a capability is enabled.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions