This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git
The following commit(s) were added to refs/heads/main by this push:
new 1439c764c fix(services/oss): fix batch delete with version for oss
(#5687)
1439c764c is described below
commit 1439c764cdec52ee7a04a4cae0b949af2f45a3ce
Author: meteorgan <[email protected]>
AuthorDate: Mon Mar 3 21:30:50 2025 +0800
fix(services/oss): fix batch delete with version for oss (#5687)
fix oss
---
core/src/services/oss/core.rs | 14 ++++++++++++--
core/src/services/oss/delete.rs | 28 ++++++++++++++--------------
2 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/core/src/services/oss/core.rs b/core/src/services/oss/core.rs
index 2f9116b86..185047b25 100644
--- a/core/src/services/oss/core.rs
+++ b/core/src/services/oss/core.rs
@@ -571,7 +571,10 @@ impl OssCore {
self.send(req).await
}
- pub async fn oss_delete_objects(&self, paths: Vec<String>) ->
Result<Response<Buffer>> {
+ pub async fn oss_delete_objects(
+ &self,
+ paths: Vec<(String, OpDelete)>,
+ ) -> Result<Response<Buffer>> {
let url = format!("{}/?delete", self.endpoint);
let req = Request::post(&url);
@@ -579,8 +582,9 @@ impl OssCore {
let content = quick_xml::se::to_string(&DeleteObjectsRequest {
object: paths
.into_iter()
- .map(|path| DeleteObjectsRequestObject {
+ .map(|(path, op)| DeleteObjectsRequestObject {
key: build_abs_path(&self.root, &path),
+ version_id: op.version().map(|v| v.to_owned()),
})
.collect(),
})
@@ -735,6 +739,8 @@ pub struct DeleteObjectsRequest {
#[serde(rename_all = "PascalCase")]
pub struct DeleteObjectsRequestObject {
pub key: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub version_id: Option<String>,
}
/// Result of DeleteObjects.
@@ -748,6 +754,7 @@ pub struct DeleteObjectsResult {
#[serde(rename_all = "PascalCase")]
pub struct DeleteObjectsResultDeleted {
pub key: String,
+ pub version_id: Option<String>,
}
#[derive(Default, Debug, Deserialize)]
@@ -866,12 +873,15 @@ mod tests {
object: vec![
DeleteObjectsRequestObject {
key: "multipart.data".to_string(),
+ version_id: None,
},
DeleteObjectsRequestObject {
key: "test.jpg".to_string(),
+ version_id: None,
},
DeleteObjectsRequestObject {
key: "demo.jpg".to_string(),
+ version_id: None,
},
],
};
diff --git a/core/src/services/oss/delete.rs b/core/src/services/oss/delete.rs
index 544cf242c..f12e0eee1 100644
--- a/core/src/services/oss/delete.rs
+++ b/core/src/services/oss/delete.rs
@@ -50,17 +50,12 @@ impl oio::BatchDelete for OssDeleter {
async fn delete_batch(&self, batch: Vec<(String, OpDelete)>) ->
Result<BatchDeleteResult> {
// Sadly, OSS will not return failed keys, so we will build
// a set to calculate the failed keys.
- let mut keys = HashSet::new();
-
- let paths = batch
- .into_iter()
- .map(|(p, _)| {
- keys.insert(p.clone());
- p
- })
+ let mut keys: HashSet<(String, OpDelete)> = batch
+ .iter()
+ .map(|path| (path.0.to_owned(), path.1.clone()))
.collect();
- let resp = self.core.oss_delete_objects(paths).await?;
+ let resp = self.core.oss_delete_objects(batch).await?;
let status = resp.status();
@@ -87,14 +82,19 @@ impl oio::BatchDelete for OssDeleter {
for i in result.deleted {
let path = build_rel_path(&self.core.root, &i.key);
- keys.remove(&path);
- batched_result.succeeded.push((path, OpDelete::default()));
+ let mut op = OpDelete::default();
+ if let Some(version) = &i.version_id {
+ op = op.with_version(version);
+ }
+ let object = (path, op);
+ keys.remove(&object);
+ batched_result.succeeded.push(object);
}
// TODO: we should handle those errors with code.
- for i in keys {
+ for (path, op) in keys {
batched_result.failed.push((
- i,
- OpDelete::default(),
+ path,
+ op,
Error::new(
ErrorKind::Unexpected,
"oss delete this key failed for reason we don't know",