@@ -399,7 +399,8 @@ bool CacheGarbageCollector::RegisterHostCleanupIntent(const std::string &instanc
399399
400400void CacheGarbageCollector::CancelHostCleanupIntent (const std::string &instance_id,
401401 DataStorageType storage_type,
402- const std::string &host_ip_port) noexcept {
402+ const std::string &host_ip_port,
403+ uint64_t active_lifecycle_generation) noexcept {
403404 try {
404405 bool canceled = false ;
405406 EventReportIntentType canceled_type = EventReportIntentType::kDownHost ;
@@ -408,7 +409,12 @@ void CacheGarbageCollector::CancelHostCleanupIntent(const std::string &instance_
408409 const EventReportIntentKey key{instance_id, storage_type, host_ip_port};
409410 recovery_observations_.erase (key);
410411 const auto it = event_report_intents_.find (key);
411- if (it != event_report_intents_.end () && it->second .type != EventReportIntentType::kStaleSnapshot ) {
412+ // A liveness callback publishes DownHost before its
413+ // generation-checked unregister. An event from that same active
414+ // lifecycle must not erase the intent in this window. Only a
415+ // strictly newer REGISTER/recovery lifecycle invalidates it.
416+ if (it != event_report_intents_.end () && it->second .type != EventReportIntentType::kStaleSnapshot &&
417+ it->second .lifecycle_generation < active_lifecycle_generation) {
412418 canceled_type = it->second .type ;
413419 event_report_intents_.erase (it);
414420 canceled = true ;
@@ -824,6 +830,14 @@ bool CacheGarbageCollector::RunEventReportTick() {
824830 for (const auto &[instance_id, _] : event_report_retry_batches_) {
825831 active_instances.insert (instance_id);
826832 }
833+ // A pass owns its frozen intent snapshot until its cursor reaches base.
834+ // Keep scheduling it even if every live intent is canceled mid-pass;
835+ // otherwise a later intent would inherit the stale cursor and barrier.
836+ for (const auto &[instance_id, state] : event_report_scan_states_) {
837+ if (state.context ) {
838+ active_instances.insert (instance_id);
839+ }
840+ }
827841 if (active_instances.empty ()) {
828842 UpdateEventReportMetrics ();
829843 return false ;
@@ -965,6 +979,11 @@ bool CacheGarbageCollector::BeginEventReportPass(const std::string &instance_id,
965979 return false ;
966980 }
967981
982+ auto indexer = meta_indexer_manager_->GetMetaIndexer (instance_id);
983+ if (!indexer || !indexer->IsMaintenanceDeleteReady ()) {
984+ FailEventReportPass (instance_id, state, indexer ? " meta_recovering" : " indexer_missing" );
985+ return false ;
986+ }
968987 MetaSearcher *meta_searcher = meta_searcher_manager_->GetMetaSearcher (instance_id);
969988 if (!meta_searcher || !meta_searcher->SyncAllForMaintenance ()) {
970989 FailEventReportPass (instance_id, state, meta_searcher ? " sync_all" : " searcher_missing" );
@@ -1094,7 +1113,8 @@ std::vector<CacheGarbageCollector::EventReportDeleteTarget> CacheGarbageCollecto
10941113 if (backend->ParseLocationId (location_id, medium, host)) {
10951114 const EventReportIntentKey key{instance_id, location->type (), host};
10961115 if (backend->IsNodeRegistered (instance_id, host)) {
1097- CancelHostCleanupIntent (instance_id, location->type (), host);
1116+ CancelHostCleanupIntent (
1117+ instance_id, location->type (), host, backend->GetNodeGeneration (instance_id, host));
10981118 } else {
10991119 std::lock_guard<std::mutex> lock (event_report_intent_mutex_);
11001120 recovery_observations_.try_emplace (
@@ -1297,6 +1317,8 @@ bool CacheGarbageCollector::ExecuteEventReportDeleteBatch(const std::string &ins
12971317 static_cast <double >(std::max<int64_t >(0 , action_duration_ms));
12981318 metrics_registry_->GetGauge (" cache_gc.event_report_last_action_shard_lock_wait_us" ) =
12991319 static_cast <double >(std::max<int64_t >(0 , result.shard_lock_wait_time_us ));
1320+ metrics_registry_->GetGauge (" cache_gc.event_report_last_action_shard_lock_hold_us" ) =
1321+ static_cast <double >(std::max<int64_t >(0 , result.shard_lock_hold_time_us ));
13001322 } catch (...) { KVCM_LOG_ERROR (" cache gc failed to record event report action metrics" ); }
13011323
13021324 if (!result.sync_succeeded || (result.ec != EC_OK && result.ec != EC_MISMATCH )) {
0 commit comments