From 59de0de6b348ec4102233f13e951e14d7aab0d65 Mon Sep 17 00:00:00 2001 From: houseme Date: Sun, 30 Aug 2026 03:10:32 +0800 Subject: [PATCH] fix(scanner): retain cleanup scope after cancellation Co-Authored-By: heihutu --- crates/scanner/src/lib.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/crates/scanner/src/lib.rs b/crates/scanner/src/lib.rs index 3a8cb8d6f..de35b0622 100644 --- a/crates/scanner/src/lib.rs +++ b/crates/scanner/src/lib.rs @@ -773,8 +773,24 @@ where } else { None }; - opts.scanner_publication_commit_scope = scanner_publication_commit_scope; - let result = api.delete_config_object(bucket, object, opts).await; + let result = if let Some(scope) = scanner_publication_commit_scope { + // Keep the storage mutation and its publication scope alive after the + // scanner persistence waiter is cancelled. The delete path can fan + // out to remote RPCs or blocking local namespace syscalls; dropping + // only the waiter must not release the movement permit early. + opts.scanner_publication_commit_scope = Some(scope.clone()); + let bucket = bucket.to_owned(); + let object = object.to_owned(); + tokio::spawn(async move { + let _publication_scope_owner = scope; + api.delete_config_object(&bucket, &object, opts).await + }) + .await + .map_err(|err| EcstoreError::other(format!("scanner publication delete owner failed: {err}")))? + } else { + opts.scanner_publication_commit_scope = None; + api.delete_config_object(bucket, object, opts).await + }; drop(legacy_admission); result }