@@ -434,7 +434,11 @@ std::optional< pg_id_t > HSHomeObject::get_pg_id_with_group_id(group_id_t group_
434434 }
435435}
436436
437- void HSHomeObject::pg_destroy (pg_id_t pg_id) {
437+ bool HSHomeObject::pg_destroy (pg_id_t pg_id, bool need_to_pause_pg_state_machine) {
438+ if (need_to_pause_pg_state_machine && !pause_pg_state_machine (pg_id)) {
439+ LOGI (" Failed to pause pg state machine, pg_id={}" , pg_id);
440+ return false ;
441+ }
438442 LOGI (" Destroying pg={}" , pg_id);
439443 mark_pg_destroyed (pg_id);
440444 destroy_shards (pg_id);
@@ -448,6 +452,35 @@ void HSHomeObject::pg_destroy(pg_id_t pg_id) {
448452 RELEASE_ASSERT (res, " Failed to return pg={} chunks to dev_heap" , pg_id);
449453
450454 LOGI (" pg={} is destroyed" , pg_id);
455+ return true ;
456+ }
457+
458+ bool HSHomeObject::pause_pg_state_machine (pg_id_t pg_id) {
459+ LOGI (" Pause pg state machine, pg={}" , pg_id);
460+ auto hs_pg = const_cast < HS_PG * >(_get_hs_pg_unlocked (pg_id));
461+ auto repl_dev = hs_pg ? hs_pg->repl_dev_ : nullptr ;
462+ auto max_wait_time_ms = 2000 ;
463+ for (auto i = 0 ; i < 2000 / 500 ; i++) {
464+ hs_pg->repl_dev_ ->pause_state_machine (500 /* ms */ );
465+ if (repl_dev->is_state_machine_paused ()) {
466+ LOGI (" pg={} state machine is paused" , pg_id);
467+ return true ;
468+ }
469+ }
470+ LOGE (" Failed to pause pg={} state machine after {} ms" , pg_id, max_wait_time_ms);
471+ return false ;
472+ }
473+
474+ bool HSHomeObject::resume_pg_state_machine (pg_id_t pg_id) {
475+ LOGI (" Resuming pg state machine, pg={}" , pg_id);
476+ auto hs_pg = const_cast < HS_PG * >(_get_hs_pg_unlocked (pg_id));
477+ auto repl_dev = hs_pg ? hs_pg->repl_dev_ : nullptr ;
478+ while (repl_dev->is_state_machine_paused ()) {
479+ hs_pg->repl_dev_ ->resume_state_machine ();
480+ std::this_thread::sleep_for (std::chrono::milliseconds (500 ));
481+ }
482+ LOGE (" Resumed pg state machine, pg=" , pg_id);
483+ return true ;
451484}
452485
453486void HSHomeObject::mark_pg_destroyed (pg_id_t pg_id) {
0 commit comments