1use std::sync::Arc;
16
17use cache::build_datanode_cache_registry;
18use catalog::kvbackend::new_read_only_meta_kv_backend;
19use common_base::Plugins;
20use common_meta::cache::LayeredCacheRegistryBuilder;
21use common_telemetry::info;
22use common_version::{short_version, verbose_version};
23use datanode::datanode::DatanodeBuilder;
24use datanode::service::DatanodeServiceBuilder;
25use meta_client::MetaClientType;
26use snafu::{OptionExt, ResultExt};
27use tracing_appender::non_blocking::WorkerGuard;
28
29use crate::datanode::{APP_NAME, DatanodeOptions, Instance};
30use crate::error::{MetaClientInitSnafu, MissingConfigSnafu, Result, StartDatanodeSnafu};
31use crate::{create_resource_limit_metrics, log_versions, maybe_activate_heap_profile};
32
33pub struct InstanceBuilder {
35 guard: Vec<WorkerGuard>,
36 opts: DatanodeOptions,
37 datanode_builder: DatanodeBuilder,
38}
39
40impl InstanceBuilder {
41 pub async fn try_new_with_init(
44 mut opts: DatanodeOptions,
45 mut plugins: Plugins,
46 ) -> Result<Self> {
47 let guard = Self::init(&mut opts, &mut plugins).await?;
48
49 let mut datanode_builder = Self::datanode_builder(&opts, &plugins).await?;
50
51 plugins::setup_datanode_plugins_post_build(&mut plugins, &opts.plugins, &datanode_builder)
52 .await
53 .context(StartDatanodeSnafu)?;
54 datanode_builder.set_plugins(plugins);
55
56 Ok(Self {
57 guard,
58 opts,
59 datanode_builder,
60 })
61 }
62
63 async fn init(opts: &mut DatanodeOptions, plugins: &mut Plugins) -> Result<Vec<WorkerGuard>> {
64 common_runtime::init_global_runtimes(&opts.runtime);
65 common_runtime::init_datanode_runtimes(&opts.runtime);
66
67 let dn_opts = &mut opts.component;
68 let guard = common_telemetry::init_global_logging(
69 APP_NAME,
70 &dn_opts.logging,
71 &dn_opts.tracing,
72 dn_opts.node_id.map(|x| x.to_string()),
73 None,
74 );
75
76 crate::options::flush_dropped_plugin_warnings();
77 log_versions(verbose_version(), short_version(), APP_NAME);
78 maybe_activate_heap_profile(&dn_opts.memory);
79 create_resource_limit_metrics(APP_NAME);
80
81 plugins::setup_datanode_plugins_pre_build(plugins, &opts.plugins, dn_opts)
82 .await
83 .context(StartDatanodeSnafu)?;
84
85 dn_opts.grpc.detect_server_addr();
86
87 info!("Initialized Datanode instance with {:#?}", opts);
88 Ok(guard)
89 }
90
91 async fn datanode_builder(
92 opts: &DatanodeOptions,
93 plugins: &Plugins,
94 ) -> Result<DatanodeBuilder> {
95 let dn_opts = &opts.component;
96
97 let member_id = dn_opts
98 .node_id
99 .context(MissingConfigSnafu { msg: "'node_id'" })?;
100 let meta_client_options = dn_opts.meta_client.as_ref().context(MissingConfigSnafu {
101 msg: "meta client options",
102 })?;
103 let client = meta_client::create_meta_client(
104 MetaClientType::Datanode { member_id },
105 meta_client_options,
106 Some(plugins),
107 None,
108 )
109 .await
110 .context(MetaClientInitSnafu)?;
111
112 let backend = new_read_only_meta_kv_backend(client.clone());
113 let mut builder = DatanodeBuilder::new(dn_opts.clone(), plugins.clone(), backend.clone());
114
115 let registry = Arc::new(
116 LayeredCacheRegistryBuilder::default()
117 .add_cache_registry(build_datanode_cache_registry(backend))
118 .build(),
119 );
120 builder
121 .with_cache_registry(registry)
122 .with_meta_client(client.clone());
123 Ok(builder)
124 }
125
126 pub fn mut_datanode_builder(&mut self) -> &mut DatanodeBuilder {
129 &mut self.datanode_builder
130 }
131
132 pub async fn build(self) -> Result<Instance> {
134 let mut datanode = self
135 .datanode_builder
136 .build()
137 .await
138 .context(StartDatanodeSnafu)?;
139
140 let services = DatanodeServiceBuilder::new(&self.opts.component)
141 .with_default_grpc_server(&datanode.region_server())
142 .enable_http_service()
143 .build()
144 .context(StartDatanodeSnafu)?;
145 datanode.setup_services(services);
146
147 Ok(Instance::new(datanode, self.guard))
148 }
149}