From f327707321d6563f9408a735a0f86770c1257a28 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Wed, 8 Jul 2026 15:01:09 +0800 Subject: [PATCH] fix(ecstore): clear lifecycle metadata cache (#4416) --- crates/ecstore/src/bucket/metadata.rs | 18 ++++++++++++++ crates/ecstore/src/bucket/metadata_sys.rs | 30 ++--------------------- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/crates/ecstore/src/bucket/metadata.rs b/crates/ecstore/src/bucket/metadata.rs index b3424cdb2..41b9063d1 100644 --- a/crates/ecstore/src/bucket/metadata.rs +++ b/crates/ecstore/src/bucket/metadata.rs @@ -689,6 +689,7 @@ impl BucketMetadata { } BUCKET_LIFECYCLE_CONFIG => { self.lifecycle_config_xml = data; + self.lifecycle_config = None; self.lifecycle_config_updated_at = updated; } BUCKET_SSECONFIG => { @@ -1240,6 +1241,23 @@ mod test { assert_eq!(bucket_targets.targets[0].target_bucket, "target-bucket"); } + #[test] + fn lifecycle_update_config_clears_parsed_config_on_delete() { + let mut bm = BucketMetadata::new("test-bucket"); + let lifecycle_xml = br#"rule1Enabled30"#; + + bm.update_config(BUCKET_LIFECYCLE_CONFIG, lifecycle_xml.to_vec()) + .expect("lifecycle config should update"); + bm.parse_all_configs().expect("lifecycle config should parse"); + assert!(bm.lifecycle_config.is_some()); + + bm.update_config(BUCKET_LIFECYCLE_CONFIG, Vec::new()) + .expect("lifecycle config delete should update metadata"); + + assert!(bm.lifecycle_config_xml.is_empty()); + assert!(bm.lifecycle_config.is_none()); + } + #[tokio::test] async fn marshal_msg_complete_example() { // Create a complete BucketMetadata with various configurations diff --git a/crates/ecstore/src/bucket/metadata_sys.rs b/crates/ecstore/src/bucket/metadata_sys.rs index 2edc43f9f..c3ce22a1c 100644 --- a/crates/ecstore/src/bucket/metadata_sys.rs +++ b/crates/ecstore/src/bucket/metadata_sys.rs @@ -16,8 +16,8 @@ use super::metadata::{BucketMetadata, load_bucket_metadata}; use super::quota::BucketQuota; use super::target::BucketTargets; use crate::bucket::bucket_target_sys::BucketTargetSys; -use crate::bucket::metadata::{BUCKET_LIFECYCLE_CONFIG, load_bucket_metadata_parse}; -use crate::bucket::utils::{deserialize, is_meta_bucketname}; +use crate::bucket::metadata::load_bucket_metadata_parse; +use crate::bucket::utils::is_meta_bucketname; use crate::error::{Error, Result, is_err_bucket_not_found}; use crate::runtime::sources as runtime_sources; use crate::storage_api_contracts::heal::HealOperations as _; @@ -454,32 +454,6 @@ impl BucketMetadataSys { } pub async fn delete(&mut self, bucket: &str, config_file: &str) -> Result { - if config_file == BUCKET_LIFECYCLE_CONFIG { - let meta = match self.get_config_from_disk(bucket).await { - Ok(res) => res, - Err(err) => { - if err != Error::ConfigNotFound { - return Err(err); - } else { - BucketMetadata::new(bucket) - } - } - }; - - if !meta.lifecycle_config_xml.is_empty() { - if let Ok(cfg) = deserialize::(&meta.lifecycle_config_xml) { - if let Some(_v) = cfg.rules.first() {} - } else { - tracing::warn!( - bucket = %bucket, - "delete: failed to parse lifecycle config XML" - ); - } - } - - // TODO: other lifecycle handle - } - self.update_and_parse(bucket, config_file, Vec::new(), false).await }