mito2/worker/
handle_close.rs1use common_telemetry::info;
18use store_api::logstore::LogStore;
19use store_api::logstore::provider::Provider;
20use store_api::region_request::{RegionFlushReason, RegionFlushRequest};
21use store_api::storage::RegionId;
22
23use crate::request::OptionOutputTx;
24use crate::worker::RegionWorkerLoop;
25
26impl<S: LogStore> RegionWorkerLoop<S> {
27 pub(crate) async fn handle_close_request(
28 &mut self,
29 region_id: RegionId,
30 sender: OptionOutputTx,
31 ) {
32 let Some(region) = self.regions.get_region(region_id) else {
33 sender.send(Ok(0));
34 return;
35 };
36
37 info!("Try to close region {}, worker: {}", region_id, self.id);
38
39 if region.provider == Provider::Noop
42 && !region
43 .version_control
44 .current()
45 .version
46 .memtables
47 .is_empty()
48 && region.is_flushable()
49 {
50 info!("Region {} has pending data, waiting for flush", region_id);
51 self.handle_flush_request(
52 region_id,
53 RegionFlushRequest {
54 reason: Some(RegionFlushReason::Closing),
55 ..Default::default()
56 },
57 sender,
58 );
59 return;
60 }
61
62 self.remove_region(region_id).await;
64 info!("Region {} closed, worker: {}", region_id, self.id);
65 sender.send(Ok(0))
66 }
67
68 pub(crate) async fn remove_region(&mut self, region_id: RegionId) {
70 let Some(region) = self.regions.remove_region(region_id) else {
71 return;
72 };
73 region.stop().await;
74 self.fail_region_stalled_requests_as_not_found(®ion_id);
75 self.reject_region_edit_queue_as_not_found(region_id);
76 self.flush_scheduler.on_region_closed(region_id);
78 self.compaction_scheduler.on_region_closed(region_id);
80 self.index_build_scheduler.on_region_closed(region_id).await;
82 self.region_count.dec();
83 }
84}