mito2/worker/
handle_close.rs1use common_telemetry::info;
18use store_api::logstore::LogStore;
19use store_api::region_request::{RegionCloseRequest, RegionFlushReason, RegionFlushRequest};
20use store_api::storage::RegionId;
21
22use crate::request::{DdlRequest, OptionOutputTx, SenderDdlRequest};
23use crate::worker::RegionWorkerLoop;
24
25impl<S: LogStore> RegionWorkerLoop<S> {
26 pub(crate) async fn handle_close_request(
27 &mut self,
28 region_id: RegionId,
29 request: RegionCloseRequest,
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.is_staging_or_staged_edit() {
40 let _manager = region.manifest_ctx.manifest_manager.write().await;
44 region.abort_staging();
45 self.reject_region_edit_queue_as_not_found(region_id);
47 }
48
49 let version = region.version();
53 if (request.flush_on_close || region.skip_wal() || version.memtables.has_skip_wal_writes())
54 && !version.memtables.is_empty()
55 && region.is_flushable()
56 {
57 info!("Region {} has pending data, waiting for flush", region_id);
58 if self.flush_scheduler.is_flush_requested(region_id) {
59 self.flush_scheduler
60 .add_ddl_request_to_pending(SenderDdlRequest {
61 region_id,
62 sender,
63 request: DdlRequest::Close(request),
64 });
65 return;
66 }
67 self.handle_flush_request(
68 region_id,
69 RegionFlushRequest {
70 reason: Some(RegionFlushReason::Closing),
71 ..Default::default()
72 },
73 sender,
74 );
75 return;
76 }
77
78 self.remove_region(region_id).await;
80 info!("Region {} closed, worker: {}", region_id, self.id);
81 sender.send(Ok(0))
82 }
83
84 pub(crate) async fn remove_region(&mut self, region_id: RegionId) {
86 let Some(region) = self.regions.remove_region(region_id) else {
87 return;
88 };
89 region.deactivate_region_manifest_size_metric();
90 region.stop().await;
91 self.fail_region_stalled_requests_as_not_found(®ion_id);
92 self.reject_region_edit_queue_as_not_found(region_id);
93 self.flush_scheduler.on_region_closed(region_id);
95 self.compaction_scheduler.on_region_closed(region_id);
97 self.index_build_scheduler.on_region_closed(region_id).await;
99 self.region_count.dec();
100
101 if let Some(hook) = region.manifest_ctx.hook() {
105 let metadata = region.metadata();
106 hook.on_region_closed(region_id, &metadata).await;
107 }
108 }
109}