metric_engine/engine/
catchup.rs1use std::collections::HashMap;
16
17use common_error::ext::BoxedError;
18use snafu::{OptionExt, ResultExt};
19use store_api::region_engine::{BatchResponses, RegionEngine};
20use store_api::region_request::{RegionCatchupRequest, ReplayCheckpoint};
21use store_api::storage::RegionId;
22
23use crate::engine::MetricEngineInner;
24use crate::error::{BatchCatchupMitoRegionSnafu, PhysicalRegionNotFoundSnafu, Result};
25use crate::utils;
26
27impl MetricEngineInner {
28 pub async fn handle_batch_catchup_requests(
29 &self,
30 parallelism: usize,
31 requests: Vec<(RegionId, RegionCatchupRequest)>,
32 ) -> Result<BatchResponses> {
33 let mut all_requests = Vec::with_capacity(requests.len() * 2);
34 let mut physical_region_options_list = Vec::with_capacity(requests.len());
35
36 for (region_id, req) in requests {
37 let metadata_region_id = utils::to_metadata_region_id(region_id);
38 let data_region_id = utils::to_data_region_id(region_id);
39
40 let physical_region_options = *self
41 .state
42 .read()
43 .unwrap()
44 .physical_region_states()
45 .get(&data_region_id)
46 .context(PhysicalRegionNotFoundSnafu {
47 region_id: data_region_id,
48 })?
49 .options();
50 physical_region_options_list.push((data_region_id, physical_region_options));
51 all_requests.push((
52 metadata_region_id,
53 RegionCatchupRequest {
54 set_writable: req.set_writable,
55 entry_id: req.metadata_entry_id,
56 metadata_entry_id: None,
57 checkpoint: req.checkpoint.map(|c| ReplayCheckpoint {
58 entry_id: c.metadata_entry_id.unwrap_or_default(),
59 metadata_entry_id: None,
60 }),
61 },
62 ));
63 all_requests.push((
64 data_region_id,
65 RegionCatchupRequest {
66 set_writable: req.set_writable,
67 entry_id: req.entry_id,
68 metadata_entry_id: None,
69 checkpoint: req.checkpoint.map(|c| ReplayCheckpoint {
70 entry_id: c.entry_id,
71 metadata_entry_id: None,
72 }),
73 },
74 ));
75 }
76
77 let mut results = self
78 .mito
79 .handle_batch_catchup_requests(parallelism, all_requests)
80 .await
81 .context(BatchCatchupMitoRegionSnafu {})?
82 .into_iter()
83 .collect::<HashMap<_, _>>();
84
85 let mut responses = Vec::with_capacity(physical_region_options_list.len());
86 for (physical_region_id, physical_region_options) in physical_region_options_list {
87 let metadata_region_id = utils::to_metadata_region_id(physical_region_id);
88 let data_region_id = utils::to_data_region_id(physical_region_id);
89 let metadata_region_result = results.remove(&metadata_region_id);
90 let data_region_result = results.remove(&data_region_id);
91
92 let response = self
97 .recover_physical_region_with_results(
98 metadata_region_result,
99 data_region_result,
100 physical_region_id,
101 physical_region_options,
102 false,
106 )
107 .await
108 .map_err(BoxedError::new);
109 responses.push((physical_region_id, response));
110 }
111
112 Ok(responses)
113 }
114}