tracking: support atomic conditional delete across services
- Dominant language
- Rust
- Stars
- 5.4k
- Forks
- 825
- Avg merge
- 1d 14m
- Merged PRs (30d)
- 127
Description
### 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 #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 #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](https://docs.github.com/en/rest/repos/contents#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](https://learn.microsoft.com/en-us/graph/api/driveitem-delete?view=graph-rest-1.0). 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](https://www.rfc-editor.org/rfc/rfc9110.html#name-if-match) defines this for state-changing methods, including `DELETE`, and [RFC 4918](https://www.rfc-editor.org/rfc/rfc4918.html#section-7.2) 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](https://cloud.google.com/storage/docs/json_api/v1/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.
Contributor guide
Research direction
No specific source file or test is named; start by reading the provider implementations and the capability advertisement paths, along with #8142 and the listed provider API references. Done means each supported service has behavior coverage for matching and mismatching deletes, preserves conditions in native batches, reports mixed results correctly, and advertises the capability only after passing live behavior tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, azure, gcp, github, rust
- Domain
- api, backend, cloud, distributed-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100