1use std::collections::{BTreeMap, HashMap, HashSet};
16use std::fmt::{Debug, Display};
17use std::sync::Arc;
18use std::sync::atomic::AtomicBool;
19use std::sync::atomic::Ordering::Relaxed;
20use std::thread;
21use std::time::{Duration, SystemTime};
22
23use anyhow::{Context, anyhow};
24use async_trait::async_trait;
25use cluster_limit_service_client::ClusterLimitServiceClient;
26use either::Either;
27use futures::stream::BoxStream;
28use list_rate_limits_response::RateLimitInfo;
29use lru::LruCache;
30use replace_job_plan::ReplaceJob;
31use risingwave_common::RW_VERSION;
32use risingwave_common::catalog::{
33 AlterDatabaseParam, FunctionId, IndexId, ObjectId, SecretId, TableId,
34};
35use risingwave_common::config::{MAX_CONNECTION_WINDOW_SIZE, MetaConfig};
36use risingwave_common::hash::WorkerSlotMapping;
37use risingwave_common::id::{
38 ConnectionId, DatabaseId, JobId, SchemaId, SinkId, SubscriptionId, UserId, ViewId, WorkerId,
39};
40use risingwave_common::monitor::EndpointExt;
41use risingwave_common::system_param::AdaptiveParallelismStrategy;
42use risingwave_common::system_param::reader::SystemParamsReader;
43use risingwave_common::telemetry::report::TelemetryInfoFetcher;
44use risingwave_common::util::addr::HostAddr;
45use risingwave_common::util::meta_addr::MetaAddressStrategy;
46use risingwave_common::util::resource_util::cpu::total_cpu_available;
47use risingwave_common::util::resource_util::hostname;
48use risingwave_common::util::resource_util::memory::system_memory_available_bytes;
49use risingwave_error::bail;
50use risingwave_error::tonic::ErrorIsFromTonicServerImpl;
51use risingwave_hummock_sdk::change_log::{TableChangeLog, TableChangeLogs};
52use risingwave_hummock_sdk::version::{HummockVersion, HummockVersionDelta};
53use risingwave_hummock_sdk::{
54 CompactionGroupId, HummockEpoch, HummockVersionId, ObjectIdRange, SyncResult,
55};
56use risingwave_pb::backup_service::backup_service_client::BackupServiceClient;
57use risingwave_pb::backup_service::*;
58use risingwave_pb::catalog::{
59 Connection, PbComment, PbDatabase, PbFunction, PbIndex, PbSchema, PbSink, PbSource,
60 PbSubscription, PbTable, PbView, Table,
61};
62use risingwave_pb::cloud_service::cloud_service_client::CloudServiceClient;
63use risingwave_pb::cloud_service::*;
64use risingwave_pb::common::worker_node::Property;
65use risingwave_pb::common::{HostAddress, OptionalUint32, OptionalUint64, WorkerNode, WorkerType};
66use risingwave_pb::configured_monitor_service_client;
67use risingwave_pb::connector_service::sink_coordination_service_client::SinkCoordinationServiceClient;
68use risingwave_pb::ddl_service::alter_owner_request::Object;
69use risingwave_pb::ddl_service::create_iceberg_table_request::{PbSinkJobInfo, PbTableJobInfo};
70use risingwave_pb::ddl_service::ddl_service_client::DdlServiceClient;
71use risingwave_pb::ddl_service::*;
72use risingwave_pb::hummock::compact_task::TaskStatus;
73use risingwave_pb::hummock::get_compaction_score_response::PickerInfo;
74use risingwave_pb::hummock::get_table_change_logs_request::PbTableFilter;
75use risingwave_pb::hummock::hummock_manager_service_client::HummockManagerServiceClient;
76use risingwave_pb::hummock::rise_ctl_update_compaction_config_request::mutable_config::MutableConfig;
77use risingwave_pb::hummock::subscribe_compaction_event_request::Register;
78use risingwave_pb::hummock::write_limits::WriteLimit;
79use risingwave_pb::hummock::*;
80use risingwave_pb::iceberg_compaction::subscribe_iceberg_compaction_event_request::Register as IcebergRegister;
81use risingwave_pb::iceberg_compaction::{
82 SubscribeIcebergCompactionEventRequest, SubscribeIcebergCompactionEventResponse,
83 subscribe_iceberg_compaction_event_request,
84};
85use risingwave_pb::id::{ActorId, FragmentId, HummockSstableId, SourceId};
86use risingwave_pb::meta::alter_connector_props_request::{
87 AlterConnectorPropsObject, AlterIcebergTableIds, ExtraOptions,
88};
89use risingwave_pb::meta::cancel_creating_jobs_request::PbJobs;
90use risingwave_pb::meta::cluster_service_client::ClusterServiceClient;
91use risingwave_pb::meta::event_log_service_client::EventLogServiceClient;
92use risingwave_pb::meta::heartbeat_service_client::HeartbeatServiceClient;
93use risingwave_pb::meta::hosted_iceberg_catalog_service_client::HostedIcebergCatalogServiceClient;
94use risingwave_pb::meta::list_actor_splits_response::ActorSplit;
95use risingwave_pb::meta::list_actor_states_response::ActorState;
96use risingwave_pb::meta::list_cdc_progress_response::PbCdcProgress;
97use risingwave_pb::meta::list_iceberg_tables_response::IcebergTable;
98use risingwave_pb::meta::list_refresh_table_states_response::RefreshTableState;
99use risingwave_pb::meta::list_streaming_job_states_response::StreamingJobState;
100use risingwave_pb::meta::list_table_fragments_response::TableFragmentInfo;
101use risingwave_pb::meta::meta_member_service_client::MetaMemberServiceClient;
102use risingwave_pb::meta::notification_service_client::NotificationServiceClient;
103use risingwave_pb::meta::scale_service_client::ScaleServiceClient;
104use risingwave_pb::meta::serving_service_client::ServingServiceClient;
105use risingwave_pb::meta::session_param_service_client::SessionParamServiceClient;
106use risingwave_pb::meta::stream_manager_service_client::StreamManagerServiceClient;
107use risingwave_pb::meta::system_params_service_client::SystemParamsServiceClient;
108use risingwave_pb::meta::telemetry_info_service_client::TelemetryInfoServiceClient;
109use risingwave_pb::meta::{FragmentDistribution, *};
110use risingwave_pb::monitor_service::monitor_service_client::MonitorServiceClient;
111use risingwave_pb::monitor_service::stack_trace_request::ActorTracesFormat;
112use risingwave_pb::monitor_service::{StackTraceRequest, StackTraceResponse};
113use risingwave_pb::secret::PbSecretRef;
114use risingwave_pb::stream_plan::StreamFragmentGraph;
115use risingwave_pb::user::alter_default_privilege_request::Operation as AlterDefaultPrivilegeOperation;
116use risingwave_pb::user::update_user_request::UpdateField;
117use risingwave_pb::user::user_service_client::UserServiceClient;
118use risingwave_pb::user::*;
119use thiserror_ext::AsReport;
120use tokio::sync::mpsc::{Receiver, UnboundedSender, unbounded_channel};
121use tokio::sync::oneshot::Sender;
122use tokio::sync::{RwLock, mpsc, oneshot};
123use tokio::task::JoinHandle;
124use tokio::time::{self};
125use tokio_retry::strategy::{ExponentialBackoff, jitter};
126use tokio_stream::wrappers::UnboundedReceiverStream;
127use tonic::transport::Endpoint;
128use tonic::{Code, Request, Streaming};
129
130use crate::channel::{Channel, WrappedChannelExt};
131use crate::error::{Result, RpcError};
132use crate::hummock_meta_client::{
133 CompactionEventItem, HummockMetaClient, HummockMetaClientChangeLogInfo,
134 IcebergCompactionEventItem,
135};
136use crate::meta_rpc_client_method_impl;
137
138#[derive(Clone, Debug)]
140pub struct MetaClient {
141 worker_id: WorkerId,
142 worker_type: WorkerType,
143 host_addr: HostAddr,
144 inner: GrpcMetaClient,
145 meta_config: Arc<MetaConfig>,
146 cluster_id: String,
147 shutting_down: Arc<AtomicBool>,
148}
149
150impl MetaClient {
151 pub fn worker_id(&self) -> WorkerId {
152 self.worker_id
153 }
154
155 pub fn host_addr(&self) -> &HostAddr {
156 &self.host_addr
157 }
158
159 pub fn worker_type(&self) -> WorkerType {
160 self.worker_type
161 }
162
163 pub fn cluster_id(&self) -> &str {
164 &self.cluster_id
165 }
166
167 pub async fn subscribe(
169 &self,
170 subscribe_type: SubscribeType,
171 ) -> Result<Streaming<SubscribeResponse>> {
172 let request = SubscribeRequest {
173 subscribe_type: subscribe_type as i32,
174 host: Some(self.host_addr.to_protobuf()),
175 worker_id: self.worker_id(),
176 };
177
178 let retry_strategy = GrpcMetaClient::retry_strategy_to_bound(
179 Duration::from_secs(self.meta_config.max_heartbeat_interval_secs as u64),
180 true,
181 );
182
183 tokio_retry::Retry::spawn(retry_strategy, || async {
184 let request = request.clone();
185 self.inner.subscribe(request).await
186 })
187 .await
188 }
189
190 pub async fn create_connection(
191 &self,
192 connection_name: String,
193 database_id: DatabaseId,
194 schema_id: SchemaId,
195 owner_id: UserId,
196 req: create_connection_request::Payload,
197 ) -> Result<WaitVersion> {
198 let request = CreateConnectionRequest {
199 name: connection_name,
200 database_id,
201 schema_id,
202 owner_id,
203 payload: Some(req),
204 };
205 let resp = self.inner.create_connection(request).await?;
206 Ok(resp
207 .version
208 .ok_or_else(|| anyhow!("wait version not set"))?)
209 }
210
211 pub async fn create_secret(
212 &self,
213 secret_name: String,
214 database_id: DatabaseId,
215 schema_id: SchemaId,
216 owner_id: UserId,
217 value: Vec<u8>,
218 ) -> Result<WaitVersion> {
219 let request = CreateSecretRequest {
220 name: secret_name,
221 database_id,
222 schema_id,
223 owner_id,
224 value,
225 };
226 let resp = self.inner.create_secret(request).await?;
227 Ok(resp
228 .version
229 .ok_or_else(|| anyhow!("wait version not set"))?)
230 }
231
232 pub async fn list_connections(&self, _name: Option<&str>) -> Result<Vec<Connection>> {
233 let request = ListConnectionsRequest {};
234 let resp = self.inner.list_connections(request).await?;
235 Ok(resp.connections)
236 }
237
238 pub async fn drop_connection(
239 &self,
240 connection_id: ConnectionId,
241 cascade: bool,
242 ) -> Result<WaitVersion> {
243 let request = DropConnectionRequest {
244 connection_id,
245 cascade,
246 };
247 let resp = self.inner.drop_connection(request).await?;
248 Ok(resp
249 .version
250 .ok_or_else(|| anyhow!("wait version not set"))?)
251 }
252
253 pub async fn drop_secret(&self, secret_id: SecretId, cascade: bool) -> Result<WaitVersion> {
254 let request = DropSecretRequest { secret_id, cascade };
255 let resp = self.inner.drop_secret(request).await?;
256 Ok(resp
257 .version
258 .ok_or_else(|| anyhow!("wait version not set"))?)
259 }
260
261 pub async fn register_new(
265 addr_strategy: MetaAddressStrategy,
266 worker_type: WorkerType,
267 addr: &HostAddr,
268 property: Property,
269 meta_config: Arc<MetaConfig>,
270 ) -> (Self, SystemParamsReader) {
271 let ret =
272 Self::register_new_inner(addr_strategy, worker_type, addr, property, meta_config).await;
273
274 match ret {
275 Ok(ret) => ret,
276 Err(err) => {
277 tracing::error!(error = %err.as_report(), "failed to register worker, exiting...");
278 std::process::exit(1);
279 }
280 }
281 }
282
283 async fn register_new_inner(
284 addr_strategy: MetaAddressStrategy,
285 worker_type: WorkerType,
286 addr: &HostAddr,
287 property: Property,
288 meta_config: Arc<MetaConfig>,
289 ) -> Result<(Self, SystemParamsReader)> {
290 tracing::info!("register meta client using strategy: {}", addr_strategy);
291
292 let retry_strategy = GrpcMetaClient::retry_strategy_to_bound(
294 Duration::from_secs(meta_config.max_heartbeat_interval_secs as u64),
295 true,
296 );
297
298 let init_result: Result<_> = tokio_retry::RetryIf::spawn(
299 retry_strategy,
300 || async {
301 let grpc_meta_client =
302 GrpcMetaClient::new(&addr_strategy, meta_config.clone()).await?;
303
304 let add_worker_resp = grpc_meta_client
305 .add_worker_node(AddWorkerNodeRequest {
306 worker_type: worker_type as i32,
307 host: Some(addr.to_protobuf()),
308 property: Some(property.clone()),
309 resource: Some(risingwave_pb::common::worker_node::Resource {
310 rw_version: RW_VERSION.to_owned(),
311 total_memory_bytes: system_memory_available_bytes() as _,
312 total_cpu_cores: total_cpu_available() as _,
313 hostname: hostname(),
314 }),
315 })
316 .await
317 .context("failed to add worker node")?;
318
319 let system_params_resp = grpc_meta_client
320 .get_system_params(GetSystemParamsRequest {})
321 .await
322 .context("failed to get initial system params")?;
323
324 Ok((add_worker_resp, system_params_resp, grpc_meta_client))
325 },
326 |e: &RpcError| !e.is_from_tonic_server_impl(),
329 )
330 .await;
331
332 let (add_worker_resp, system_params_resp, grpc_meta_client) = init_result?;
333 let worker_id = add_worker_resp
334 .node_id
335 .expect("AddWorkerNodeResponse::node_id is empty");
336
337 let meta_client = Self {
338 worker_id,
339 worker_type,
340 host_addr: addr.clone(),
341 inner: grpc_meta_client,
342 meta_config: meta_config.clone(),
343 cluster_id: add_worker_resp.cluster_id,
344 shutting_down: Arc::new(false.into()),
345 };
346
347 static REPORT_PANIC: std::sync::Once = std::sync::Once::new();
348 REPORT_PANIC.call_once(|| {
349 let meta_client_clone = meta_client.clone();
350 std::panic::update_hook(move |default_hook, info| {
351 meta_client_clone.try_add_panic_event_blocking(info, None);
353 default_hook(info);
354 });
355 });
356
357 Ok((meta_client, system_params_resp.params.unwrap().into()))
358 }
359
360 pub async fn activate(&self, addr: &HostAddr) -> Result<()> {
362 let request = ActivateWorkerNodeRequest {
363 host: Some(addr.to_protobuf()),
364 node_id: self.worker_id,
365 };
366 let retry_strategy = GrpcMetaClient::retry_strategy_to_bound(
367 Duration::from_secs(self.meta_config.max_heartbeat_interval_secs as u64),
368 true,
369 );
370 tokio_retry::Retry::spawn(retry_strategy, || async {
371 let request = request.clone();
372 self.inner.activate_worker_node(request).await
373 })
374 .await?;
375
376 Ok(())
377 }
378
379 pub async fn send_heartbeat(&self) -> Result<()> {
381 let request = HeartbeatRequest {
382 node_id: self.worker_id,
383 resource: Some(risingwave_pb::common::worker_node::Resource {
384 rw_version: RW_VERSION.to_owned(),
385 total_memory_bytes: system_memory_available_bytes() as _,
386 total_cpu_cores: total_cpu_available() as _,
387 hostname: hostname(),
388 }),
389 };
390 let resp = self.inner.heartbeat(request).await?;
391 if let Some(status) = resp.status
392 && status.code() == risingwave_pb::common::status::Code::UnknownWorker
393 {
394 if !self.shutting_down.load(Relaxed) {
397 tracing::error!(message = status.message, "worker expired");
398 std::process::exit(1);
399 }
400 }
401 Ok(())
402 }
403
404 pub async fn create_database(&self, db: PbDatabase) -> Result<WaitVersion> {
405 let request = CreateDatabaseRequest { db: Some(db) };
406 let resp = self.inner.create_database(request).await?;
407 Ok(resp
409 .version
410 .ok_or_else(|| anyhow!("wait version not set"))?)
411 }
412
413 pub async fn create_schema(&self, schema: PbSchema) -> Result<WaitVersion> {
414 let request = CreateSchemaRequest {
415 schema: Some(schema),
416 };
417 let resp = self.inner.create_schema(request).await?;
418 Ok(resp
420 .version
421 .ok_or_else(|| anyhow!("wait version not set"))?)
422 }
423
424 pub async fn create_materialized_view(
425 &self,
426 table: PbTable,
427 graph: StreamFragmentGraph,
428 dependencies: HashSet<ObjectId>,
429 resource_type: streaming_job_resource_type::ResourceType,
430 if_not_exists: bool,
431 refresh_interval_sec: Option<u64>,
432 ) -> Result<WaitVersion> {
433 let request = CreateMaterializedViewRequest {
434 materialized_view: Some(table),
435 fragment_graph: Some(graph),
436 resource_type: Some(PbStreamingJobResourceType {
437 resource_type: Some(resource_type),
438 }),
439 dependencies: dependencies.into_iter().collect(),
440 if_not_exists,
441 refresh_interval_sec,
442 };
443 let resp = self.inner.create_materialized_view(request).await?;
444 Ok(resp
446 .version
447 .ok_or_else(|| anyhow!("wait version not set"))?)
448 }
449
450 pub async fn drop_materialized_view(
451 &self,
452 table_id: TableId,
453 cascade: bool,
454 ) -> Result<WaitVersion> {
455 let request = DropMaterializedViewRequest { table_id, cascade };
456
457 let resp = self.inner.drop_materialized_view(request).await?;
458 Ok(resp
459 .version
460 .ok_or_else(|| anyhow!("wait version not set"))?)
461 }
462
463 pub async fn create_source(
464 &self,
465 source: PbSource,
466 graph: Option<StreamFragmentGraph>,
467 if_not_exists: bool,
468 ) -> Result<WaitVersion> {
469 let request = CreateSourceRequest {
470 source: Some(source),
471 fragment_graph: graph,
472 if_not_exists,
473 };
474
475 let resp = self.inner.create_source(request).await?;
476 Ok(resp
477 .version
478 .ok_or_else(|| anyhow!("wait version not set"))?)
479 }
480
481 pub async fn create_sink(
482 &self,
483 sink: PbSink,
484 graph: StreamFragmentGraph,
485 dependencies: HashSet<ObjectId>,
486 resource_type: streaming_job_resource_type::ResourceType,
487 if_not_exists: bool,
488 since_timestamp_epoch: Option<u64>,
489 ) -> Result<WaitVersion> {
490 let request = CreateSinkRequest {
491 sink: Some(sink),
492 fragment_graph: Some(graph),
493 dependencies: dependencies.into_iter().collect(),
494 if_not_exists,
495 resource_type: Some(PbStreamingJobResourceType {
496 resource_type: Some(resource_type),
497 }),
498 since_timestamp_epoch,
499 };
500
501 let resp = self.inner.create_sink(request).await?;
502 Ok(resp
503 .version
504 .ok_or_else(|| anyhow!("wait version not set"))?)
505 }
506
507 pub async fn create_subscription(&self, subscription: PbSubscription) -> Result<WaitVersion> {
508 let request = CreateSubscriptionRequest {
509 subscription: Some(subscription),
510 };
511
512 let resp = self.inner.create_subscription(request).await?;
513 Ok(resp
514 .version
515 .ok_or_else(|| anyhow!("wait version not set"))?)
516 }
517
518 pub async fn create_function(&self, function: PbFunction) -> Result<WaitVersion> {
519 let request = CreateFunctionRequest {
520 function: Some(function),
521 };
522 let resp = self.inner.create_function(request).await?;
523 Ok(resp
524 .version
525 .ok_or_else(|| anyhow!("wait version not set"))?)
526 }
527
528 pub async fn create_table(
529 &self,
530 source: Option<PbSource>,
531 table: PbTable,
532 graph: StreamFragmentGraph,
533 job_type: PbTableJobType,
534 if_not_exists: bool,
535 dependencies: HashSet<ObjectId>,
536 ) -> Result<WaitVersion> {
537 let request = CreateTableRequest {
538 materialized_view: Some(table),
539 fragment_graph: Some(graph),
540 source,
541 job_type: job_type as _,
542 if_not_exists,
543 dependencies: dependencies.into_iter().collect(),
544 };
545 let resp = self.inner.create_table(request).await?;
546 Ok(resp
548 .version
549 .ok_or_else(|| anyhow!("wait version not set"))?)
550 }
551
552 pub async fn comment_on(&self, comment: PbComment) -> Result<WaitVersion> {
553 let request = CommentOnRequest {
554 comment: Some(comment),
555 };
556 let resp = self.inner.comment_on(request).await?;
557 Ok(resp
558 .version
559 .ok_or_else(|| anyhow!("wait version not set"))?)
560 }
561
562 pub async fn alter_name(
563 &self,
564 object: alter_name_request::Object,
565 name: &str,
566 ) -> Result<WaitVersion> {
567 let request = AlterNameRequest {
568 object: Some(object),
569 new_name: name.to_owned(),
570 };
571 let resp = self.inner.alter_name(request).await?;
572 Ok(resp
573 .version
574 .ok_or_else(|| anyhow!("wait version not set"))?)
575 }
576
577 pub async fn alter_owner(&self, object: Object, owner_id: UserId) -> Result<WaitVersion> {
578 let request = AlterOwnerRequest {
579 object: Some(object),
580 owner_id,
581 };
582 let resp = self.inner.alter_owner(request).await?;
583 Ok(resp
584 .version
585 .ok_or_else(|| anyhow!("wait version not set"))?)
586 }
587
588 pub async fn alter_subscription_retention(
589 &self,
590 subscription_id: SubscriptionId,
591 retention_seconds: u64,
592 definition: String,
593 ) -> Result<WaitVersion> {
594 let request = AlterSubscriptionRetentionRequest {
595 subscription_id,
596 retention_seconds,
597 definition,
598 };
599 let resp = self.inner.alter_subscription_retention(request).await?;
600 Ok(resp
601 .version
602 .ok_or_else(|| anyhow!("wait version not set"))?)
603 }
604
605 pub async fn alter_database_param(
606 &self,
607 database_id: DatabaseId,
608 param: AlterDatabaseParam,
609 ) -> Result<WaitVersion> {
610 let request = match param {
611 AlterDatabaseParam::BarrierIntervalMs(barrier_interval_ms) => {
612 let barrier_interval_ms = OptionalUint32 {
613 value: barrier_interval_ms,
614 };
615 AlterDatabaseParamRequest {
616 database_id,
617 param: Some(alter_database_param_request::Param::BarrierIntervalMs(
618 barrier_interval_ms,
619 )),
620 }
621 }
622 AlterDatabaseParam::CheckpointFrequency(checkpoint_frequency) => {
623 let checkpoint_frequency = OptionalUint64 {
624 value: checkpoint_frequency,
625 };
626 AlterDatabaseParamRequest {
627 database_id,
628 param: Some(alter_database_param_request::Param::CheckpointFrequency(
629 checkpoint_frequency,
630 )),
631 }
632 }
633 };
634 let resp = self.inner.alter_database_param(request).await?;
635 Ok(resp
636 .version
637 .ok_or_else(|| anyhow!("wait version not set"))?)
638 }
639
640 pub async fn alter_set_schema(
641 &self,
642 object: alter_set_schema_request::Object,
643 new_schema_id: SchemaId,
644 ) -> Result<WaitVersion> {
645 let request = AlterSetSchemaRequest {
646 new_schema_id,
647 object: Some(object),
648 };
649 let resp = self.inner.alter_set_schema(request).await?;
650 Ok(resp
651 .version
652 .ok_or_else(|| anyhow!("wait version not set"))?)
653 }
654
655 pub async fn alter_source(&self, source: PbSource) -> Result<WaitVersion> {
656 let request = AlterSourceRequest {
657 source: Some(source),
658 };
659 let resp = self.inner.alter_source(request).await?;
660 Ok(resp
661 .version
662 .ok_or_else(|| anyhow!("wait version not set"))?)
663 }
664
665 pub async fn alter_parallelism(
666 &self,
667 job_id: JobId,
668 parallelism: PbTableParallelism,
669 adaptive_parallelism_strategy: Option<AdaptiveParallelismStrategy>,
670 deferred: bool,
671 ) -> Result<()> {
672 let request = AlterParallelismRequest {
673 table_id: job_id,
674 parallelism: Some(parallelism),
675 deferred,
676 adaptive_parallelism_strategy: adaptive_parallelism_strategy
677 .map(|strategy| strategy.to_string()),
678 };
679
680 self.inner.alter_parallelism(request).await?;
681 Ok(())
682 }
683
684 pub async fn alter_backfill_parallelism(
685 &self,
686 job_id: JobId,
687 parallelism: Option<PbTableParallelism>,
688 adaptive_parallelism_strategy: Option<AdaptiveParallelismStrategy>,
689 deferred: bool,
690 ) -> Result<()> {
691 let request = AlterBackfillParallelismRequest {
692 table_id: job_id,
693 parallelism,
694 deferred,
695 adaptive_parallelism_strategy: adaptive_parallelism_strategy
696 .map(|strategy| strategy.to_string()),
697 };
698
699 self.inner.alter_backfill_parallelism(request).await?;
700 Ok(())
701 }
702
703 pub async fn alter_streaming_job_config(
704 &self,
705 job_id: JobId,
706 entries_to_add: HashMap<String, String>,
707 keys_to_remove: Vec<String>,
708 ) -> Result<()> {
709 let request = AlterStreamingJobConfigRequest {
710 job_id,
711 entries_to_add,
712 keys_to_remove,
713 };
714
715 self.inner.alter_streaming_job_config(request).await?;
716 Ok(())
717 }
718
719 pub async fn alter_fragment_parallelism(
720 &self,
721 fragment_ids: Vec<FragmentId>,
722 parallelism: Option<PbTableParallelism>,
723 ) -> Result<()> {
724 let request = AlterFragmentParallelismRequest {
725 fragment_ids,
726 parallelism,
727 };
728
729 self.inner.alter_fragment_parallelism(request).await?;
730 Ok(())
731 }
732
733 pub async fn alter_cdc_table_backfill_parallelism(
734 &self,
735 table_id: JobId,
736 parallelism: PbTableParallelism,
737 ) -> Result<()> {
738 let request = AlterCdcTableBackfillParallelismRequest {
739 table_id,
740 parallelism: Some(parallelism),
741 };
742 self.inner
743 .alter_cdc_table_backfill_parallelism(request)
744 .await?;
745 Ok(())
746 }
747
748 pub async fn alter_resource_group(
749 &self,
750 job_id: JobId,
751 resource_group: Option<String>,
752 deferred: bool,
753 ) -> Result<()> {
754 let request = AlterResourceGroupRequest {
755 job_id,
756 resource_group,
757 deferred,
758 };
759
760 self.inner.alter_resource_group(request).await?;
761 Ok(())
762 }
763
764 pub async fn alter_database_resource_group(
765 &self,
766 database_id: DatabaseId,
767 resource_group: Option<String>,
768 deferred: bool,
769 ) -> Result<WaitVersion> {
770 let request = AlterDatabaseResourceGroupRequest {
771 database_id,
772 resource_group,
773 deferred,
774 };
775
776 let resp = self.inner.alter_database_resource_group(request).await?;
777 Ok(resp
778 .version
779 .ok_or_else(|| anyhow!("wait version not set"))?)
780 }
781
782 pub async fn alter_swap_rename(
783 &self,
784 object: alter_swap_rename_request::Object,
785 ) -> Result<WaitVersion> {
786 let request = AlterSwapRenameRequest {
787 object: Some(object),
788 };
789 let resp = self.inner.alter_swap_rename(request).await?;
790 Ok(resp
791 .version
792 .ok_or_else(|| anyhow!("wait version not set"))?)
793 }
794
795 pub async fn alter_secret(
796 &self,
797 secret_id: SecretId,
798 secret_name: String,
799 database_id: DatabaseId,
800 schema_id: SchemaId,
801 owner_id: UserId,
802 value: Vec<u8>,
803 ) -> Result<WaitVersion> {
804 let request = AlterSecretRequest {
805 secret_id,
806 name: secret_name,
807 database_id,
808 schema_id,
809 owner_id,
810 value,
811 };
812 let resp = self.inner.alter_secret(request).await?;
813 Ok(resp
814 .version
815 .ok_or_else(|| anyhow!("wait version not set"))?)
816 }
817
818 pub async fn replace_job(
819 &self,
820 graph: StreamFragmentGraph,
821 replace_job: ReplaceJob,
822 ) -> Result<WaitVersion> {
823 let request = ReplaceJobPlanRequest {
824 plan: Some(ReplaceJobPlan {
825 fragment_graph: Some(graph),
826 replace_job: Some(replace_job),
827 }),
828 };
829 let resp = self.inner.replace_job_plan(request).await?;
830 Ok(resp
832 .version
833 .ok_or_else(|| anyhow!("wait version not set"))?)
834 }
835
836 pub async fn auto_schema_change(&self, schema_change: SchemaChangeEnvelope) -> Result<()> {
837 let request = AutoSchemaChangeRequest {
838 schema_change: Some(schema_change),
839 };
840 let _ = self.inner.auto_schema_change(request).await?;
841 Ok(())
842 }
843
844 pub async fn create_view(
845 &self,
846 view: PbView,
847 dependencies: HashSet<ObjectId>,
848 ) -> Result<WaitVersion> {
849 let request = CreateViewRequest {
850 view: Some(view),
851 dependencies: dependencies.into_iter().collect(),
852 };
853 let resp = self.inner.create_view(request).await?;
854 Ok(resp
856 .version
857 .ok_or_else(|| anyhow!("wait version not set"))?)
858 }
859
860 pub async fn create_index(
861 &self,
862 index: PbIndex,
863 table: PbTable,
864 graph: StreamFragmentGraph,
865 resource_type: streaming_job_resource_type::ResourceType,
866 if_not_exists: bool,
867 ) -> Result<WaitVersion> {
868 let request = CreateIndexRequest {
869 index: Some(index),
870 index_table: Some(table),
871 fragment_graph: Some(graph),
872 if_not_exists,
873 resource_type: Some(PbStreamingJobResourceType {
874 resource_type: Some(resource_type),
875 }),
876 };
877 let resp = self.inner.create_index(request).await?;
878 Ok(resp
880 .version
881 .ok_or_else(|| anyhow!("wait version not set"))?)
882 }
883
884 pub async fn drop_table(
885 &self,
886 source_id: Option<SourceId>,
887 table_id: TableId,
888 cascade: bool,
889 ) -> Result<WaitVersion> {
890 let request = DropTableRequest {
891 source_id: source_id.map(risingwave_pb::ddl_service::drop_table_request::SourceId::Id),
892 table_id,
893 cascade,
894 };
895
896 let resp = self.inner.drop_table(request).await?;
897 Ok(resp
898 .version
899 .ok_or_else(|| anyhow!("wait version not set"))?)
900 }
901
902 pub async fn compact_iceberg_table(&self, sink_id: SinkId) -> Result<u64> {
903 let request = CompactIcebergTableRequest { sink_id };
904 let resp = self.inner.compact_iceberg_table(request).await?;
905 Ok(resp.task_id)
906 }
907
908 pub async fn expire_iceberg_table_snapshots(&self, sink_id: SinkId) -> Result<()> {
909 let request = ExpireIcebergTableSnapshotsRequest { sink_id };
910 let _resp = self.inner.expire_iceberg_table_snapshots(request).await?;
911 Ok(())
912 }
913
914 pub async fn drop_view(&self, view_id: ViewId, cascade: bool) -> Result<WaitVersion> {
915 let request = DropViewRequest { view_id, cascade };
916 let resp = self.inner.drop_view(request).await?;
917 Ok(resp
918 .version
919 .ok_or_else(|| anyhow!("wait version not set"))?)
920 }
921
922 pub async fn drop_source(&self, source_id: SourceId, cascade: bool) -> Result<WaitVersion> {
923 let request = DropSourceRequest { source_id, cascade };
924 let resp = self.inner.drop_source(request).await?;
925 Ok(resp
926 .version
927 .ok_or_else(|| anyhow!("wait version not set"))?)
928 }
929
930 pub async fn reset_source(&self, source_id: SourceId) -> Result<WaitVersion> {
931 let request = ResetSourceRequest { source_id };
932 let resp = self.inner.reset_source(request).await?;
933 Ok(resp
934 .version
935 .ok_or_else(|| anyhow!("wait version not set"))?)
936 }
937
938 pub async fn drop_sink(&self, sink_id: SinkId, cascade: bool) -> Result<WaitVersion> {
939 let request = DropSinkRequest { sink_id, cascade };
940 let resp = self.inner.drop_sink(request).await?;
941 Ok(resp
942 .version
943 .ok_or_else(|| anyhow!("wait version not set"))?)
944 }
945
946 pub async fn drop_subscription(
947 &self,
948 subscription_id: SubscriptionId,
949 cascade: bool,
950 ) -> Result<WaitVersion> {
951 let request = DropSubscriptionRequest {
952 subscription_id,
953 cascade,
954 };
955 let resp = self.inner.drop_subscription(request).await?;
956 Ok(resp
957 .version
958 .ok_or_else(|| anyhow!("wait version not set"))?)
959 }
960
961 pub async fn drop_index(&self, index_id: IndexId, cascade: bool) -> Result<WaitVersion> {
962 let request = DropIndexRequest { index_id, cascade };
963 let resp = self.inner.drop_index(request).await?;
964 Ok(resp
965 .version
966 .ok_or_else(|| anyhow!("wait version not set"))?)
967 }
968
969 pub async fn drop_function(
970 &self,
971 function_id: FunctionId,
972 cascade: bool,
973 ) -> Result<WaitVersion> {
974 let request = DropFunctionRequest {
975 function_id,
976 cascade,
977 };
978 let resp = self.inner.drop_function(request).await?;
979 Ok(resp
980 .version
981 .ok_or_else(|| anyhow!("wait version not set"))?)
982 }
983
984 pub async fn drop_database(&self, database_id: DatabaseId) -> Result<WaitVersion> {
985 let request = DropDatabaseRequest { database_id };
986 let resp = self.inner.drop_database(request).await?;
987 Ok(resp
988 .version
989 .ok_or_else(|| anyhow!("wait version not set"))?)
990 }
991
992 pub async fn drop_schema(&self, schema_id: SchemaId, cascade: bool) -> Result<WaitVersion> {
993 let request = DropSchemaRequest { schema_id, cascade };
994 let resp = self.inner.drop_schema(request).await?;
995 Ok(resp
996 .version
997 .ok_or_else(|| anyhow!("wait version not set"))?)
998 }
999
1000 pub async fn create_user(&self, user: UserInfo) -> Result<u64> {
1002 let request = CreateUserRequest { user: Some(user) };
1003 let resp = self.inner.create_user(request).await?;
1004 Ok(resp.version)
1005 }
1006
1007 pub async fn drop_user(&self, user_id: UserId) -> Result<u64> {
1008 let request = DropUserRequest { user_id };
1009 let resp = self.inner.drop_user(request).await?;
1010 Ok(resp.version)
1011 }
1012
1013 pub async fn update_user(
1014 &self,
1015 user: UserInfo,
1016 update_fields: Vec<UpdateField>,
1017 ) -> Result<u64> {
1018 let request = UpdateUserRequest {
1019 user: Some(user),
1020 update_fields: update_fields
1021 .into_iter()
1022 .map(|field| field as i32)
1023 .collect::<Vec<_>>(),
1024 };
1025 let resp = self.inner.update_user(request).await?;
1026 Ok(resp.version)
1027 }
1028
1029 pub async fn grant_privilege(
1030 &self,
1031 user_ids: Vec<UserId>,
1032 privileges: Vec<GrantPrivilege>,
1033 with_grant_option: bool,
1034 granted_by: UserId,
1035 ) -> Result<u64> {
1036 let request = GrantPrivilegeRequest {
1037 user_ids,
1038 privileges,
1039 with_grant_option,
1040 granted_by,
1041 };
1042 let resp = self.inner.grant_privilege(request).await?;
1043 Ok(resp.version)
1044 }
1045
1046 pub async fn revoke_privilege(
1047 &self,
1048 user_ids: Vec<UserId>,
1049 privileges: Vec<GrantPrivilege>,
1050 granted_by: UserId,
1051 revoke_by: UserId,
1052 revoke_grant_option: bool,
1053 cascade: bool,
1054 ) -> Result<u64> {
1055 let request = RevokePrivilegeRequest {
1056 user_ids,
1057 privileges,
1058 granted_by,
1059 revoke_by,
1060 revoke_grant_option,
1061 cascade,
1062 };
1063 let resp = self.inner.revoke_privilege(request).await?;
1064 Ok(resp.version)
1065 }
1066
1067 pub async fn alter_default_privilege(
1068 &self,
1069 user_ids: Vec<UserId>,
1070 database_id: DatabaseId,
1071 schema_ids: Vec<SchemaId>,
1072 operation: AlterDefaultPrivilegeOperation,
1073 granted_by: UserId,
1074 ) -> Result<()> {
1075 let request = AlterDefaultPrivilegeRequest {
1076 user_ids,
1077 database_id,
1078 schema_ids,
1079 operation: Some(operation),
1080 granted_by,
1081 };
1082 self.inner.alter_default_privilege(request).await?;
1083 Ok(())
1084 }
1085
1086 pub async fn unregister(&self) -> Result<()> {
1088 let request = DeleteWorkerNodeRequest {
1089 host: Some(self.host_addr.to_protobuf()),
1090 };
1091 self.inner.delete_worker_node(request).await?;
1092 self.shutting_down.store(true, Relaxed);
1093 Ok(())
1094 }
1095
1096 pub async fn try_unregister(&self) {
1098 match self.unregister().await {
1099 Ok(_) => {
1100 tracing::info!(
1101 worker_id = %self.worker_id(),
1102 "successfully unregistered from meta service",
1103 )
1104 }
1105 Err(e) => {
1106 tracing::warn!(
1107 error = %e.as_report(),
1108 worker_id = %self.worker_id(),
1109 "failed to unregister from meta service",
1110 );
1111 }
1112 }
1113 }
1114
1115 pub async fn list_worker_nodes(
1116 &self,
1117 worker_type: Option<WorkerType>,
1118 ) -> Result<Vec<WorkerNode>> {
1119 let request = ListAllNodesRequest {
1120 worker_type: worker_type.map(Into::into),
1121 include_starting_nodes: true,
1122 };
1123 let resp = self.inner.list_all_nodes(request).await?;
1124 Ok(resp.nodes)
1125 }
1126
1127 pub fn start_heartbeat_loop(
1129 meta_client: MetaClient,
1130 min_interval: Duration,
1131 ) -> (JoinHandle<()>, Sender<()>) {
1132 let (shutdown_tx, mut shutdown_rx) = tokio::sync::oneshot::channel();
1133 let join_handle = tokio::spawn(async move {
1134 let mut min_interval_ticker = tokio::time::interval(min_interval);
1135 loop {
1136 tokio::select! {
1137 biased;
1138 _ = &mut shutdown_rx => {
1140 tracing::info!("Heartbeat loop is stopped");
1141 return;
1142 }
1143 _ = min_interval_ticker.tick() => {},
1145 }
1146 tracing::debug!(target: "events::meta::client_heartbeat", "heartbeat");
1147 match tokio::time::timeout(
1148 min_interval * 3,
1150 meta_client.send_heartbeat(),
1151 )
1152 .await
1153 {
1154 Ok(Ok(_)) => {}
1155 Ok(Err(err)) => {
1156 tracing::warn!(error = %err.as_report(), "Failed to send_heartbeat");
1157 }
1158 Err(_) => {
1159 tracing::warn!("Failed to send_heartbeat: timeout");
1160 }
1161 }
1162 }
1163 });
1164 (join_handle, shutdown_tx)
1165 }
1166
1167 pub async fn risectl_list_state_tables(&self) -> Result<Vec<PbTable>> {
1168 let request = RisectlListStateTablesRequest {};
1169 let resp = self.inner.risectl_list_state_tables(request).await?;
1170 Ok(resp.tables)
1171 }
1172
1173 pub async fn risectl_resume_backfill(
1174 &self,
1175 request: RisectlResumeBackfillRequest,
1176 ) -> Result<()> {
1177 self.inner.risectl_resume_backfill(request).await?;
1178 Ok(())
1179 }
1180
1181 pub async fn flush(&self, database_id: DatabaseId) -> Result<HummockVersionId> {
1182 let request = FlushRequest { database_id };
1183 let resp = self.inner.flush(request).await?;
1184 Ok(resp.hummock_version_id)
1185 }
1186
1187 pub async fn wait(&self, job_id: Option<JobId>) -> Result<WaitVersion> {
1188 let request = WaitRequest { job_id };
1189 let resp = self.inner.wait(request).await?;
1190 Ok(resp
1191 .version
1192 .ok_or_else(|| anyhow!("wait version not set"))?)
1193 }
1194
1195 pub async fn recover(&self) -> Result<()> {
1196 let request = RecoverRequest {};
1197 self.inner.recover(request).await?;
1198 Ok(())
1199 }
1200
1201 pub async fn cancel_creating_jobs(&self, jobs: PbJobs) -> Result<Vec<u32>> {
1202 let request = CancelCreatingJobsRequest { jobs: Some(jobs) };
1203 let resp = self.inner.cancel_creating_jobs(request).await?;
1204 Ok(resp.canceled_jobs)
1205 }
1206
1207 pub async fn list_table_fragments(
1208 &self,
1209 job_ids: &[JobId],
1210 ) -> Result<HashMap<JobId, TableFragmentInfo>> {
1211 let request = ListTableFragmentsRequest {
1212 table_ids: job_ids.to_vec(),
1213 };
1214 let resp = self.inner.list_table_fragments(request).await?;
1215 Ok(resp.table_fragments)
1216 }
1217
1218 pub async fn list_streaming_job_states(&self) -> Result<Vec<StreamingJobState>> {
1219 let resp = self
1220 .inner
1221 .list_streaming_job_states(ListStreamingJobStatesRequest {})
1222 .await?;
1223 Ok(resp.states)
1224 }
1225
1226 pub async fn list_fragment_distributions(
1227 &self,
1228 include_node: bool,
1229 ) -> Result<Vec<FragmentDistribution>> {
1230 let resp = self
1231 .inner
1232 .list_fragment_distribution(ListFragmentDistributionRequest {
1233 include_node: Some(include_node),
1234 })
1235 .await?;
1236 Ok(resp.distributions)
1237 }
1238
1239 pub async fn list_creating_fragment_distribution(&self) -> Result<Vec<FragmentDistribution>> {
1240 let resp = self
1241 .inner
1242 .list_creating_fragment_distribution(ListCreatingFragmentDistributionRequest {
1243 include_node: Some(true),
1244 })
1245 .await?;
1246 Ok(resp.distributions)
1247 }
1248
1249 pub async fn get_fragment_by_id(
1250 &self,
1251 fragment_id: FragmentId,
1252 ) -> Result<Option<FragmentDistribution>> {
1253 let resp = self
1254 .inner
1255 .get_fragment_by_id(GetFragmentByIdRequest { fragment_id })
1256 .await?;
1257 Ok(resp.distribution)
1258 }
1259
1260 pub async fn get_fragment_vnodes(
1261 &self,
1262 fragment_id: FragmentId,
1263 ) -> Result<Vec<(ActorId, Vec<u32>)>> {
1264 let resp = self
1265 .inner
1266 .get_fragment_vnodes(GetFragmentVnodesRequest { fragment_id })
1267 .await?;
1268 Ok(resp
1269 .actor_vnodes
1270 .into_iter()
1271 .map(|actor| (actor.actor_id, actor.vnode_indices))
1272 .collect())
1273 }
1274
1275 pub async fn get_actor_vnodes(&self, actor_id: ActorId) -> Result<Vec<u32>> {
1276 let resp = self
1277 .inner
1278 .get_actor_vnodes(GetActorVnodesRequest { actor_id })
1279 .await?;
1280 Ok(resp.vnode_indices)
1281 }
1282
1283 pub async fn list_actor_states(&self) -> Result<Vec<ActorState>> {
1284 let resp = self
1285 .inner
1286 .list_actor_states(ListActorStatesRequest {})
1287 .await?;
1288 Ok(resp.states)
1289 }
1290
1291 pub async fn list_actor_splits(&self) -> Result<Vec<ActorSplit>> {
1292 let resp = self
1293 .inner
1294 .list_actor_splits(ListActorSplitsRequest {})
1295 .await?;
1296
1297 Ok(resp.actor_splits)
1298 }
1299
1300 pub async fn pause(&self) -> Result<PauseResponse> {
1301 let request = PauseRequest {};
1302 let resp = self.inner.pause(request).await?;
1303 Ok(resp)
1304 }
1305
1306 pub async fn resume(&self) -> Result<ResumeResponse> {
1307 let request = ResumeRequest {};
1308 let resp = self.inner.resume(request).await?;
1309 Ok(resp)
1310 }
1311
1312 pub async fn apply_throttle(
1313 &self,
1314 throttle_target: PbThrottleTarget,
1315 throttle_type: risingwave_pb::common::PbThrottleType,
1316 id: u32,
1317 rate: Option<u32>,
1318 ) -> Result<ApplyThrottleResponse> {
1319 let request = ApplyThrottleRequest {
1320 throttle_target: throttle_target as i32,
1321 throttle_type: throttle_type as i32,
1322 id,
1323 rate,
1324 };
1325 let resp = self.inner.apply_throttle(request).await?;
1326 Ok(resp)
1327 }
1328
1329 pub async fn get_cluster_recovery_status(&self) -> Result<RecoveryStatus> {
1330 let resp = self
1331 .inner
1332 .get_cluster_recovery_status(GetClusterRecoveryStatusRequest {})
1333 .await?;
1334 Ok(resp.get_status().unwrap())
1335 }
1336
1337 pub async fn get_cluster_info(&self) -> Result<GetClusterInfoResponse> {
1338 let request = GetClusterInfoRequest {};
1339 let resp = self.inner.get_cluster_info(request).await?;
1340 Ok(resp)
1341 }
1342
1343 pub async fn reschedule(
1344 &self,
1345 worker_reschedules: HashMap<u32, PbWorkerReschedule>,
1346 revision: u64,
1347 resolve_no_shuffle_upstream: bool,
1348 ) -> Result<(bool, u64)> {
1349 let request = RescheduleRequest {
1350 revision,
1351 resolve_no_shuffle_upstream,
1352 worker_reschedules,
1353 };
1354 let resp = self.inner.reschedule(request).await?;
1355 Ok((resp.success, resp.revision))
1356 }
1357
1358 pub async fn risectl_get_pinned_versions_summary(
1359 &self,
1360 ) -> Result<RiseCtlGetPinnedVersionsSummaryResponse> {
1361 let request = RiseCtlGetPinnedVersionsSummaryRequest {};
1362 self.inner
1363 .rise_ctl_get_pinned_versions_summary(request)
1364 .await
1365 }
1366
1367 pub async fn risectl_get_checkpoint_hummock_version(
1368 &self,
1369 ) -> Result<RiseCtlGetCheckpointVersionResponse> {
1370 let request = RiseCtlGetCheckpointVersionRequest {};
1371 self.inner.rise_ctl_get_checkpoint_version(request).await
1372 }
1373
1374 pub async fn risectl_pause_hummock_version_checkpoint(
1375 &self,
1376 ) -> Result<RiseCtlPauseVersionCheckpointResponse> {
1377 let request = RiseCtlPauseVersionCheckpointRequest {};
1378 self.inner.rise_ctl_pause_version_checkpoint(request).await
1379 }
1380
1381 pub async fn risectl_resume_hummock_version_checkpoint(
1382 &self,
1383 ) -> Result<RiseCtlResumeVersionCheckpointResponse> {
1384 let request = RiseCtlResumeVersionCheckpointRequest {};
1385 self.inner.rise_ctl_resume_version_checkpoint(request).await
1386 }
1387
1388 pub async fn init_metadata_for_replay(
1389 &self,
1390 tables: Vec<PbTable>,
1391 compaction_groups: Vec<CompactionGroupInfo>,
1392 ) -> Result<()> {
1393 let req = InitMetadataForReplayRequest {
1394 tables,
1395 compaction_groups,
1396 };
1397 let _resp = self.inner.init_metadata_for_replay(req).await?;
1398 Ok(())
1399 }
1400
1401 pub async fn replay_version_delta(
1402 &self,
1403 version_delta: HummockVersionDelta,
1404 ) -> Result<(HummockVersion, Vec<CompactionGroupId>)> {
1405 let req = ReplayVersionDeltaRequest {
1406 version_delta: Some(version_delta.into()),
1407 };
1408 let resp = self.inner.replay_version_delta(req).await?;
1409 Ok((
1410 HummockVersion::from_rpc_protobuf(&resp.version.unwrap()),
1411 resp.modified_compaction_groups,
1412 ))
1413 }
1414
1415 pub async fn list_version_deltas(
1416 &self,
1417 start_id: HummockVersionId,
1418 num_limit: u32,
1419 committed_epoch_limit: HummockEpoch,
1420 ) -> Result<Vec<HummockVersionDelta>> {
1421 let req = ListVersionDeltasRequest {
1422 start_id,
1423 num_limit,
1424 committed_epoch_limit,
1425 };
1426 Ok(self
1427 .inner
1428 .list_version_deltas(req)
1429 .await?
1430 .version_deltas
1431 .unwrap()
1432 .version_deltas
1433 .iter()
1434 .map(HummockVersionDelta::from_rpc_protobuf)
1435 .collect())
1436 }
1437
1438 pub async fn trigger_compaction_deterministic(
1439 &self,
1440 version_id: HummockVersionId,
1441 compaction_groups: Vec<CompactionGroupId>,
1442 ) -> Result<()> {
1443 let req = TriggerCompactionDeterministicRequest {
1444 version_id,
1445 compaction_groups,
1446 };
1447 self.inner.trigger_compaction_deterministic(req).await?;
1448 Ok(())
1449 }
1450
1451 pub async fn disable_commit_epoch(&self) -> Result<HummockVersion> {
1452 let req = DisableCommitEpochRequest {};
1453 Ok(HummockVersion::from_rpc_protobuf(
1454 &self
1455 .inner
1456 .disable_commit_epoch(req)
1457 .await?
1458 .current_version
1459 .unwrap(),
1460 ))
1461 }
1462
1463 pub async fn get_assigned_compact_task_num(&self) -> Result<usize> {
1464 let req = GetAssignedCompactTaskNumRequest {};
1465 let resp = self.inner.get_assigned_compact_task_num(req).await?;
1466 Ok(resp.num_tasks as usize)
1467 }
1468
1469 pub async fn risectl_list_compaction_group(&self) -> Result<Vec<CompactionGroupInfo>> {
1470 let req = RiseCtlListCompactionGroupRequest {};
1471 let resp = self.inner.rise_ctl_list_compaction_group(req).await?;
1472 Ok(resp.compaction_groups)
1473 }
1474
1475 pub async fn risectl_update_compaction_config(
1476 &self,
1477 compaction_groups: &[CompactionGroupId],
1478 configs: &[MutableConfig],
1479 ) -> Result<()> {
1480 let req = RiseCtlUpdateCompactionConfigRequest {
1481 compaction_group_ids: compaction_groups.to_vec(),
1482 configs: configs
1483 .iter()
1484 .map(
1485 |c| rise_ctl_update_compaction_config_request::MutableConfig {
1486 mutable_config: Some(c.clone()),
1487 },
1488 )
1489 .collect(),
1490 };
1491 let _resp = self.inner.rise_ctl_update_compaction_config(req).await?;
1492 Ok(())
1493 }
1494
1495 pub async fn backup_meta(&self, remarks: Option<String>) -> Result<u64> {
1496 let req = BackupMetaRequest { remarks };
1497 let resp = self.inner.backup_meta(req).await?;
1498 Ok(resp.job_id)
1499 }
1500
1501 pub async fn get_backup_job_status(&self, job_id: u64) -> Result<(BackupJobStatus, String)> {
1502 let req = GetBackupJobStatusRequest { job_id };
1503 let resp = self.inner.get_backup_job_status(req).await?;
1504 Ok((resp.job_status(), resp.message))
1505 }
1506
1507 pub async fn delete_meta_snapshot(&self, snapshot_ids: &[u64]) -> Result<()> {
1508 let req = DeleteMetaSnapshotRequest {
1509 snapshot_ids: snapshot_ids.to_vec(),
1510 };
1511 let _resp = self.inner.delete_meta_snapshot(req).await?;
1512 Ok(())
1513 }
1514
1515 pub async fn get_meta_snapshot_manifest(&self) -> Result<MetaSnapshotManifest> {
1516 let req = GetMetaSnapshotManifestRequest {};
1517 let resp = self.inner.get_meta_snapshot_manifest(req).await?;
1518 Ok(resp.manifest.expect("should exist"))
1519 }
1520
1521 pub async fn get_telemetry_info(&self) -> Result<TelemetryInfoResponse> {
1522 let req = GetTelemetryInfoRequest {};
1523 let resp = self.inner.get_telemetry_info(req).await?;
1524 Ok(resp)
1525 }
1526
1527 pub async fn get_meta_store_endpoint(&self) -> Result<String> {
1528 let req = GetMetaStoreInfoRequest {};
1529 let resp = self.inner.get_meta_store_info(req).await?;
1530 Ok(resp.meta_store_endpoint)
1531 }
1532
1533 pub async fn alter_sink_props(
1534 &self,
1535 sink_id: SinkId,
1536 changed_props: BTreeMap<String, String>,
1537 changed_secret_refs: BTreeMap<String, PbSecretRef>,
1538 connector_conn_ref: Option<ConnectionId>,
1539 ) -> Result<()> {
1540 let req = AlterConnectorPropsRequest {
1541 object_id: sink_id.as_raw_id(),
1542 changed_props: changed_props.into_iter().collect(),
1543 changed_secret_refs: changed_secret_refs.into_iter().collect(),
1544 connector_conn_ref,
1545 object_type: AlterConnectorPropsObject::Sink as i32,
1546 extra_options: None,
1547 };
1548 let _resp = self.inner.alter_connector_props(req).await?;
1549 Ok(())
1550 }
1551
1552 pub async fn alter_iceberg_table_props(
1553 &self,
1554 table_id: TableId,
1555 sink_id: SinkId,
1556 source_id: SourceId,
1557 changed_props: BTreeMap<String, String>,
1558 changed_secret_refs: BTreeMap<String, PbSecretRef>,
1559 connector_conn_ref: Option<ConnectionId>,
1560 ) -> Result<()> {
1561 let req = AlterConnectorPropsRequest {
1562 object_id: table_id.as_raw_id(),
1563 changed_props: changed_props.into_iter().collect(),
1564 changed_secret_refs: changed_secret_refs.into_iter().collect(),
1565 connector_conn_ref,
1566 object_type: AlterConnectorPropsObject::IcebergTable as i32,
1567 extra_options: Some(ExtraOptions::AlterIcebergTableIds(AlterIcebergTableIds {
1568 sink_id,
1569 source_id,
1570 })),
1571 };
1572 let _resp = self.inner.alter_connector_props(req).await?;
1573 Ok(())
1574 }
1575
1576 pub async fn alter_source_connector_props(
1577 &self,
1578 source_id: SourceId,
1579 changed_props: BTreeMap<String, String>,
1580 changed_secret_refs: BTreeMap<String, PbSecretRef>,
1581 connector_conn_ref: Option<ConnectionId>,
1582 ) -> Result<()> {
1583 let req = AlterConnectorPropsRequest {
1584 object_id: source_id.as_raw_id(),
1585 changed_props: changed_props.into_iter().collect(),
1586 changed_secret_refs: changed_secret_refs.into_iter().collect(),
1587 connector_conn_ref,
1588 object_type: AlterConnectorPropsObject::Source as i32,
1589 extra_options: None,
1590 };
1591 let _resp = self.inner.alter_connector_props(req).await?;
1592 Ok(())
1593 }
1594
1595 pub async fn alter_connection_connector_props(
1596 &self,
1597 connection_id: u32,
1598 changed_props: BTreeMap<String, String>,
1599 changed_secret_refs: BTreeMap<String, PbSecretRef>,
1600 ) -> Result<()> {
1601 let req = AlterConnectorPropsRequest {
1602 object_id: connection_id,
1603 changed_props: changed_props.into_iter().collect(),
1604 changed_secret_refs: changed_secret_refs.into_iter().collect(),
1605 connector_conn_ref: None, object_type: AlterConnectorPropsObject::Connection as i32,
1607 extra_options: None,
1608 };
1609 let _resp = self.inner.alter_connector_props(req).await?;
1610 Ok(())
1611 }
1612
1613 pub async fn alter_source_properties_safe(
1616 &self,
1617 source_id: SourceId,
1618 changed_props: BTreeMap<String, String>,
1619 changed_secret_refs: BTreeMap<String, PbSecretRef>,
1620 reset_splits: bool,
1621 ) -> Result<()> {
1622 let req = AlterSourcePropertiesSafeRequest {
1623 source_id: source_id.as_raw_id(),
1624 changed_props: changed_props.into_iter().collect(),
1625 changed_secret_refs: changed_secret_refs.into_iter().collect(),
1626 options: Some(PropertyUpdateOptions { reset_splits }),
1627 };
1628 let _resp = self.inner.alter_source_properties_safe(req).await?;
1629 Ok(())
1630 }
1631
1632 pub async fn reset_source_splits(&self, source_id: SourceId) -> Result<()> {
1635 let req = ResetSourceSplitsRequest {
1636 source_id: source_id.as_raw_id(),
1637 };
1638 let _resp = self.inner.reset_source_splits(req).await?;
1639 Ok(())
1640 }
1641
1642 pub async fn inject_source_offsets(
1645 &self,
1646 source_id: SourceId,
1647 split_offsets: HashMap<String, String>,
1648 ) -> Result<Vec<String>> {
1649 let req = InjectSourceOffsetsRequest {
1650 source_id: source_id.as_raw_id(),
1651 split_offsets,
1652 };
1653 let resp = self.inner.inject_source_offsets(req).await?;
1654 Ok(resp.applied_split_ids)
1655 }
1656
1657 pub async fn set_system_param(
1658 &self,
1659 param: String,
1660 value: Option<String>,
1661 ) -> Result<Option<SystemParamsReader>> {
1662 let req = SetSystemParamRequest { param, value };
1663 let resp = self.inner.set_system_param(req).await?;
1664 Ok(resp.params.map(SystemParamsReader::from))
1665 }
1666
1667 pub async fn get_session_params(&self) -> Result<String> {
1668 let req = GetSessionParamsRequest {};
1669 let resp = self.inner.get_session_params(req).await?;
1670 Ok(resp.params)
1671 }
1672
1673 pub async fn set_session_param(&self, param: String, value: Option<String>) -> Result<String> {
1674 let req = SetSessionParamRequest { param, value };
1675 let resp = self.inner.set_session_param(req).await?;
1676 Ok(resp.param)
1677 }
1678
1679 pub async fn get_ddl_progress(&self) -> Result<Vec<DdlProgress>> {
1680 let req = GetDdlProgressRequest {};
1681 let resp = self.inner.get_ddl_progress(req).await?;
1682 Ok(resp.ddl_progress)
1683 }
1684
1685 pub async fn split_compaction_group(
1686 &self,
1687 group_id: CompactionGroupId,
1688 table_ids_to_new_group: &[TableId],
1689 partition_vnode_count: u32,
1690 ) -> Result<CompactionGroupId> {
1691 let req = SplitCompactionGroupRequest {
1692 group_id,
1693 table_ids: table_ids_to_new_group.to_vec(),
1694 partition_vnode_count,
1695 };
1696 let resp = self.inner.split_compaction_group(req).await?;
1697 Ok(resp.new_group_id)
1698 }
1699
1700 pub async fn get_tables(
1701 &self,
1702 table_ids: Vec<TableId>,
1703 include_dropped_tables: bool,
1704 ) -> Result<HashMap<TableId, Table>> {
1705 let req = GetTablesRequest {
1706 table_ids,
1707 include_dropped_tables,
1708 };
1709 let resp = self.inner.get_tables(req).await?;
1710 Ok(resp.tables)
1711 }
1712
1713 pub async fn list_serving_vnode_mappings(
1714 &self,
1715 ) -> Result<HashMap<FragmentId, (JobId, WorkerSlotMapping)>> {
1716 let req = GetServingVnodeMappingsRequest {};
1717 let resp = self.inner.get_serving_vnode_mappings(req).await?;
1718 let mappings = resp
1719 .worker_slot_mappings
1720 .into_iter()
1721 .map(|p| {
1722 (
1723 p.fragment_id,
1724 (
1725 resp.fragment_to_table
1726 .get(&p.fragment_id)
1727 .cloned()
1728 .unwrap_or_default(),
1729 WorkerSlotMapping::from_protobuf(p.mapping.as_ref().unwrap()),
1730 ),
1731 )
1732 })
1733 .collect();
1734 Ok(mappings)
1735 }
1736
1737 pub async fn risectl_list_compaction_status(
1738 &self,
1739 ) -> Result<(
1740 Vec<CompactStatus>,
1741 Vec<CompactTaskAssignment>,
1742 Vec<CompactTaskProgress>,
1743 )> {
1744 let req = RiseCtlListCompactionStatusRequest {};
1745 let resp = self.inner.rise_ctl_list_compaction_status(req).await?;
1746 Ok((
1747 resp.compaction_statuses,
1748 resp.task_assignment,
1749 resp.task_progress,
1750 ))
1751 }
1752
1753 pub async fn get_compaction_score(
1754 &self,
1755 compaction_group_id: CompactionGroupId,
1756 ) -> Result<Vec<PickerInfo>> {
1757 let req = GetCompactionScoreRequest {
1758 compaction_group_id,
1759 };
1760 let resp = self.inner.get_compaction_score(req).await?;
1761 Ok(resp.scores)
1762 }
1763
1764 pub async fn risectl_rebuild_table_stats(&self) -> Result<()> {
1765 let req = RiseCtlRebuildTableStatsRequest {};
1766 let _resp = self.inner.rise_ctl_rebuild_table_stats(req).await?;
1767 Ok(())
1768 }
1769
1770 pub async fn list_branched_object(&self) -> Result<Vec<BranchedObject>> {
1771 let req = ListBranchedObjectRequest {};
1772 let resp = self.inner.list_branched_object(req).await?;
1773 Ok(resp.branched_objects)
1774 }
1775
1776 pub async fn list_active_write_limit(&self) -> Result<HashMap<CompactionGroupId, WriteLimit>> {
1777 let req = ListActiveWriteLimitRequest {};
1778 let resp = self.inner.list_active_write_limit(req).await?;
1779 Ok(resp.write_limits)
1780 }
1781
1782 pub async fn list_hummock_meta_config(&self) -> Result<HashMap<String, String>> {
1783 let req = ListHummockMetaConfigRequest {};
1784 let resp = self.inner.list_hummock_meta_config(req).await?;
1785 Ok(resp.configs)
1786 }
1787
1788 pub async fn get_table_change_logs(
1789 &self,
1790 epoch_only: bool,
1791 start_epoch_inclusive: Option<u64>,
1792 end_epoch_inclusive: Option<u64>,
1793 table_ids: Option<HashSet<TableId>>,
1794 exclude_empty: bool,
1795 limit: Option<u32>,
1796 ) -> Result<TableChangeLogs> {
1797 let req = GetTableChangeLogsRequest {
1798 epoch_only,
1799 start_epoch_inclusive,
1800 end_epoch_inclusive,
1801 table_ids: table_ids.map(|iter| PbTableFilter {
1802 table_ids: iter.into_iter().collect::<Vec<_>>(),
1803 }),
1804 exclude_empty,
1805 limit,
1806 };
1807 let resp = self.inner.get_table_change_logs(req).await?;
1808 Ok(resp
1809 .table_change_logs
1810 .into_iter()
1811 .map(|(id, change_log)| (TableId::new(id), TableChangeLog::from_protobuf(&change_log)))
1812 .collect())
1813 }
1814
1815 pub async fn delete_worker_node(&self, worker: HostAddress) -> Result<()> {
1816 let _resp = self
1817 .inner
1818 .delete_worker_node(DeleteWorkerNodeRequest { host: Some(worker) })
1819 .await?;
1820
1821 Ok(())
1822 }
1823
1824 pub async fn rw_cloud_validate_source(
1825 &self,
1826 source_type: SourceType,
1827 source_config: HashMap<String, String>,
1828 ) -> Result<RwCloudValidateSourceResponse> {
1829 let req = RwCloudValidateSourceRequest {
1830 source_type: source_type.into(),
1831 source_config,
1832 };
1833 let resp = self.inner.rw_cloud_validate_source(req).await?;
1834 Ok(resp)
1835 }
1836
1837 pub async fn sink_coordinate_client(&self) -> SinkCoordinationRpcClient {
1838 self.inner.core.read().await.sink_coordinate_client.clone()
1839 }
1840
1841 pub async fn list_compact_task_assignment(&self) -> Result<Vec<CompactTaskAssignment>> {
1842 let req = ListCompactTaskAssignmentRequest {};
1843 let resp = self.inner.list_compact_task_assignment(req).await?;
1844 Ok(resp.task_assignment)
1845 }
1846
1847 pub async fn list_event_log(&self) -> Result<Vec<EventLog>> {
1848 let req = ListEventLogRequest::default();
1849 let resp = self.inner.list_event_log(req).await?;
1850 Ok(resp.event_logs)
1851 }
1852
1853 pub async fn list_compact_task_progress(&self) -> Result<Vec<CompactTaskProgress>> {
1854 let req = ListCompactTaskProgressRequest {};
1855 let resp = self.inner.list_compact_task_progress(req).await?;
1856 Ok(resp.task_progress)
1857 }
1858
1859 #[cfg(madsim)]
1860 pub fn try_add_panic_event_blocking(
1861 &self,
1862 panic_info: impl Display,
1863 timeout_millis: Option<u64>,
1864 ) {
1865 }
1866
1867 #[cfg(not(madsim))]
1869 pub fn try_add_panic_event_blocking(
1870 &self,
1871 panic_info: impl Display,
1872 timeout_millis: Option<u64>,
1873 ) {
1874 let event = event_log::EventWorkerNodePanic {
1875 worker_id: self.worker_id,
1876 worker_type: self.worker_type.into(),
1877 host_addr: Some(self.host_addr.to_protobuf()),
1878 panic_info: format!("{panic_info}"),
1879 };
1880 let grpc_meta_client = self.inner.clone();
1881 let _ = thread::spawn(move || {
1882 let rt = tokio::runtime::Builder::new_current_thread()
1883 .enable_all()
1884 .build()
1885 .unwrap();
1886 let req = AddEventLogRequest {
1887 event: Some(add_event_log_request::Event::WorkerNodePanic(event)),
1888 };
1889 rt.block_on(async {
1890 let _ = tokio::time::timeout(
1891 Duration::from_millis(timeout_millis.unwrap_or(1000)),
1892 grpc_meta_client.add_event_log(req),
1893 )
1894 .await;
1895 });
1896 })
1897 .join();
1898 }
1899
1900 pub async fn add_sink_fail_evet(
1901 &self,
1902 sink_id: SinkId,
1903 sink_name: String,
1904 connector: String,
1905 error: String,
1906 ) -> Result<()> {
1907 let event = event_log::EventSinkFail {
1908 sink_id,
1909 sink_name,
1910 connector,
1911 error,
1912 };
1913 let req = AddEventLogRequest {
1914 event: Some(add_event_log_request::Event::SinkFail(event)),
1915 };
1916 self.inner.add_event_log(req).await?;
1917 Ok(())
1918 }
1919
1920 pub async fn add_cdc_auto_schema_change_fail_event(
1921 &self,
1922 source_id: SourceId,
1923 table_name: String,
1924 cdc_table_id: String,
1925 upstream_ddl: String,
1926 fail_info: String,
1927 ) -> Result<()> {
1928 let event = event_log::EventAutoSchemaChangeFail {
1929 table_id: source_id.as_cdc_table_id(),
1930 table_name,
1931 cdc_table_id,
1932 upstream_ddl,
1933 fail_info,
1934 };
1935 let req = AddEventLogRequest {
1936 event: Some(add_event_log_request::Event::AutoSchemaChangeFail(event)),
1937 };
1938 self.inner.add_event_log(req).await?;
1939 Ok(())
1940 }
1941
1942 pub async fn cancel_compact_task(&self, task_id: u64, task_status: TaskStatus) -> Result<bool> {
1943 let req = CancelCompactTaskRequest {
1944 task_id,
1945 task_status: task_status as _,
1946 };
1947 let resp = self.inner.cancel_compact_task(req).await?;
1948 Ok(resp.ret)
1949 }
1950
1951 pub async fn get_version_by_epoch(
1952 &self,
1953 epoch: HummockEpoch,
1954 table_id: TableId,
1955 ) -> Result<PbHummockVersion> {
1956 let req = GetVersionByEpochRequest { epoch, table_id };
1957 let resp = self.inner.get_version_by_epoch(req).await?;
1958 Ok(resp.version.unwrap())
1959 }
1960
1961 pub async fn get_cluster_limits(
1962 &self,
1963 ) -> Result<Vec<risingwave_common::util::cluster_limit::ClusterLimit>> {
1964 let req = GetClusterLimitsRequest {};
1965 let resp = self.inner.get_cluster_limits(req).await?;
1966 Ok(resp.active_limits.into_iter().map(|l| l.into()).collect())
1967 }
1968
1969 pub async fn merge_compaction_group(
1970 &self,
1971 left_group_id: CompactionGroupId,
1972 right_group_id: CompactionGroupId,
1973 ) -> Result<()> {
1974 let req = MergeCompactionGroupRequest {
1975 left_group_id,
1976 right_group_id,
1977 };
1978 self.inner.merge_compaction_group(req).await?;
1979 Ok(())
1980 }
1981
1982 pub async fn list_rate_limits(&self) -> Result<Vec<RateLimitInfo>> {
1984 let request = ListRateLimitsRequest {};
1985 let resp = self.inner.list_rate_limits(request).await?;
1986 Ok(resp.rate_limits)
1987 }
1988
1989 pub async fn list_cdc_progress(&self) -> Result<HashMap<JobId, PbCdcProgress>> {
1990 let request = ListCdcProgressRequest {};
1991 let resp = self.inner.list_cdc_progress(request).await?;
1992 Ok(resp.cdc_progress)
1993 }
1994
1995 pub async fn list_refresh_table_states(&self) -> Result<Vec<RefreshTableState>> {
1996 let request = ListRefreshTableStatesRequest {};
1997 let resp = self.inner.list_refresh_table_states(request).await?;
1998 Ok(resp.states)
1999 }
2000
2001 pub async fn list_iceberg_compaction_status(
2002 &self,
2003 ) -> Result<Vec<list_iceberg_compaction_status_response::IcebergCompactionStatus>> {
2004 let request = ListIcebergCompactionStatusRequest {};
2005 let resp = self.inner.list_iceberg_compaction_status(request).await?;
2006 Ok(resp.statuses)
2007 }
2008
2009 pub async fn list_sink_log_store_tables(
2010 &self,
2011 ) -> Result<Vec<list_sink_log_store_tables_response::SinkLogStoreTable>> {
2012 let request = ListSinkLogStoreTablesRequest {};
2013 let resp = self.inner.list_sink_log_store_tables(request).await?;
2014 Ok(resp.tables)
2015 }
2016
2017 pub async fn create_iceberg_table(
2018 &self,
2019 table_job_info: PbTableJobInfo,
2020 sink_job_info: PbSinkJobInfo,
2021 iceberg_source: PbSource,
2022 if_not_exists: bool,
2023 ) -> Result<WaitVersion> {
2024 let request = CreateIcebergTableRequest {
2025 table_info: Some(table_job_info),
2026 sink_info: Some(sink_job_info),
2027 iceberg_source: Some(iceberg_source),
2028 if_not_exists,
2029 };
2030
2031 let resp = Box::pin(self.inner.create_iceberg_table(request)).await?;
2032 Ok(resp
2033 .version
2034 .ok_or_else(|| anyhow!("wait version not set"))?)
2035 }
2036
2037 pub async fn list_hosted_iceberg_tables(&self) -> Result<Vec<IcebergTable>> {
2038 let request = ListIcebergTablesRequest {};
2039 let resp = self.inner.list_iceberg_tables(request).await?;
2040 Ok(resp.iceberg_tables)
2041 }
2042
2043 pub async fn get_cluster_stack_trace(
2045 &self,
2046 actor_traces_format: ActorTracesFormat,
2047 ) -> Result<StackTraceResponse> {
2048 let request = StackTraceRequest {
2049 actor_traces_format: actor_traces_format as i32,
2050 };
2051 let resp = self.inner.stack_trace(request).await?;
2052 Ok(resp)
2053 }
2054
2055 pub async fn set_sync_log_store_aligned(&self, job_id: JobId, aligned: bool) -> Result<()> {
2056 let request = SetSyncLogStoreAlignedRequest { job_id, aligned };
2057 self.inner.set_sync_log_store_aligned(request).await?;
2058 Ok(())
2059 }
2060
2061 pub async fn refresh(&self, request: RefreshRequest) -> Result<RefreshResponse> {
2062 self.inner.refresh(request).await
2063 }
2064
2065 pub async fn list_unmigrated_tables(&self) -> Result<HashMap<TableId, String>> {
2066 let request = ListUnmigratedTablesRequest {};
2067 let resp = self.inner.list_unmigrated_tables(request).await?;
2068 Ok(resp
2069 .tables
2070 .into_iter()
2071 .map(|table| (table.table_id, table.table_name))
2072 .collect())
2073 }
2074}
2075
2076#[async_trait]
2077impl HummockMetaClient for MetaClient {
2078 async fn unpin_version_before(&self, unpin_version_before: HummockVersionId) -> Result<()> {
2079 let req = UnpinVersionBeforeRequest {
2080 context_id: self.worker_id(),
2081 unpin_version_before,
2082 };
2083 self.inner.unpin_version_before(req).await?;
2084 Ok(())
2085 }
2086
2087 async fn get_current_version(&self) -> Result<HummockVersion> {
2088 let req = GetCurrentVersionRequest::default();
2089 Ok(HummockVersion::from_rpc_protobuf(
2090 &self
2091 .inner
2092 .get_current_version(req)
2093 .await?
2094 .current_version
2095 .unwrap(),
2096 ))
2097 }
2098
2099 async fn get_new_object_ids(&self, number: u32) -> Result<ObjectIdRange> {
2100 let resp = self
2101 .inner
2102 .get_new_object_ids(GetNewObjectIdsRequest { number })
2103 .await?;
2104 Ok(ObjectIdRange::new(resp.start_id, resp.end_id))
2105 }
2106
2107 async fn commit_epoch_with_change_log(
2108 &self,
2109 _epoch: HummockEpoch,
2110 _sync_result: SyncResult,
2111 _change_log_info: Option<HummockMetaClientChangeLogInfo>,
2112 ) -> Result<()> {
2113 panic!("Only meta service can commit_epoch in production.")
2114 }
2115
2116 async fn trigger_manual_compaction(
2117 &self,
2118 compaction_group_id: CompactionGroupId,
2119 table_id: JobId,
2120 level: u32,
2121 target_level: Option<u32>,
2122 sst_ids: Vec<HummockSstableId>,
2123 exclusive: bool,
2124 ) -> Result<bool> {
2125 let req = TriggerManualCompactionRequest {
2127 compaction_group_id,
2128 table_id,
2129 level,
2132 target_level,
2133 sst_ids,
2134 exclusive: Some(exclusive),
2135 ..Default::default()
2136 };
2137
2138 let resp = self.inner.trigger_manual_compaction(req).await?;
2139 Ok(resp.should_retry.unwrap_or(false))
2140 }
2141
2142 async fn trigger_full_gc(
2143 &self,
2144 sst_retention_time_sec: u64,
2145 prefix: Option<String>,
2146 ) -> Result<()> {
2147 self.inner
2148 .trigger_full_gc(TriggerFullGcRequest {
2149 sst_retention_time_sec,
2150 prefix,
2151 })
2152 .await?;
2153 Ok(())
2154 }
2155
2156 async fn subscribe_compaction_event(
2157 &self,
2158 ) -> Result<(
2159 UnboundedSender<SubscribeCompactionEventRequest>,
2160 BoxStream<'static, CompactionEventItem>,
2161 )> {
2162 let (request_sender, request_receiver) =
2163 unbounded_channel::<SubscribeCompactionEventRequest>();
2164 request_sender
2165 .send(SubscribeCompactionEventRequest {
2166 event: Some(subscribe_compaction_event_request::Event::Register(
2167 Register {
2168 context_id: self.worker_id(),
2169 },
2170 )),
2171 create_at: SystemTime::now()
2172 .duration_since(SystemTime::UNIX_EPOCH)
2173 .expect("Clock may have gone backwards")
2174 .as_millis() as u64,
2175 })
2176 .context("Failed to subscribe compaction event")?;
2177
2178 let stream = self
2179 .inner
2180 .subscribe_compaction_event(Request::new(UnboundedReceiverStream::new(
2181 request_receiver,
2182 )))
2183 .await?;
2184
2185 Ok((request_sender, Box::pin(stream)))
2186 }
2187
2188 async fn get_version_by_epoch(
2189 &self,
2190 epoch: HummockEpoch,
2191 table_id: TableId,
2192 ) -> Result<PbHummockVersion> {
2193 self.get_version_by_epoch(epoch, table_id).await
2194 }
2195
2196 async fn subscribe_iceberg_compaction_event(
2197 &self,
2198 ) -> Result<(
2199 UnboundedSender<SubscribeIcebergCompactionEventRequest>,
2200 BoxStream<'static, IcebergCompactionEventItem>,
2201 )> {
2202 let (request_sender, request_receiver) =
2203 unbounded_channel::<SubscribeIcebergCompactionEventRequest>();
2204 request_sender
2205 .send(SubscribeIcebergCompactionEventRequest {
2206 event: Some(subscribe_iceberg_compaction_event_request::Event::Register(
2207 IcebergRegister {
2208 context_id: self.worker_id(),
2209 },
2210 )),
2211 create_at: SystemTime::now()
2212 .duration_since(SystemTime::UNIX_EPOCH)
2213 .expect("Clock may have gone backwards")
2214 .as_millis() as u64,
2215 })
2216 .context("Failed to subscribe compaction event")?;
2217
2218 let stream = self
2219 .inner
2220 .subscribe_iceberg_compaction_event(Request::new(UnboundedReceiverStream::new(
2221 request_receiver,
2222 )))
2223 .await?;
2224
2225 Ok((request_sender, Box::pin(stream)))
2226 }
2227
2228 async fn get_table_change_logs(
2229 &self,
2230 epoch_only: bool,
2231 start_epoch_inclusive: Option<u64>,
2232 end_epoch_inclusive: Option<u64>,
2233 table_ids: Option<HashSet<TableId>>,
2234 exclude_empty: bool,
2235 limit: Option<u32>,
2236 ) -> Result<TableChangeLogs> {
2237 self.get_table_change_logs(
2238 epoch_only,
2239 start_epoch_inclusive,
2240 end_epoch_inclusive,
2241 table_ids,
2242 exclude_empty,
2243 limit,
2244 )
2245 .await
2246 }
2247}
2248
2249#[async_trait]
2250impl TelemetryInfoFetcher for MetaClient {
2251 async fn fetch_telemetry_info(&self) -> std::result::Result<Option<String>, String> {
2252 let resp = self
2253 .get_telemetry_info()
2254 .await
2255 .map_err(|e| e.to_report_string())?;
2256 let tracking_id = resp.get_tracking_id().ok();
2257 Ok(tracking_id.map(|id| id.to_owned()))
2258 }
2259}
2260
2261pub type SinkCoordinationRpcClient = SinkCoordinationServiceClient<Channel>;
2262
2263#[derive(Debug, Clone)]
2264struct GrpcMetaClientCore {
2265 cluster_client: ClusterServiceClient<Channel>,
2266 meta_member_client: MetaMemberServiceClient<Channel>,
2267 heartbeat_client: HeartbeatServiceClient<Channel>,
2268 ddl_client: DdlServiceClient<Channel>,
2269 hummock_client: HummockManagerServiceClient<Channel>,
2270 notification_client: NotificationServiceClient<Channel>,
2271 stream_client: StreamManagerServiceClient<Channel>,
2272 user_client: UserServiceClient<Channel>,
2273 scale_client: ScaleServiceClient<Channel>,
2274 backup_client: BackupServiceClient<Channel>,
2275 telemetry_client: TelemetryInfoServiceClient<Channel>,
2276 system_params_client: SystemParamsServiceClient<Channel>,
2277 session_params_client: SessionParamServiceClient<Channel>,
2278 serving_client: ServingServiceClient<Channel>,
2279 cloud_client: CloudServiceClient<Channel>,
2280 sink_coordinate_client: SinkCoordinationRpcClient,
2281 event_log_client: EventLogServiceClient<Channel>,
2282 cluster_limit_client: ClusterLimitServiceClient<Channel>,
2283 hosted_iceberg_catalog_service_client: HostedIcebergCatalogServiceClient<Channel>,
2284 monitor_client: MonitorServiceClient<Channel>,
2285}
2286
2287impl GrpcMetaClientCore {
2288 pub(crate) fn new(channel: Channel) -> Self {
2289 let cluster_client = ClusterServiceClient::new(channel.clone());
2290 let meta_member_client = MetaMemberClient::new(channel.clone());
2291 let heartbeat_client = HeartbeatServiceClient::new(channel.clone());
2292 let ddl_client =
2293 DdlServiceClient::new(channel.clone()).max_decoding_message_size(usize::MAX);
2294 let hummock_client =
2295 HummockManagerServiceClient::new(channel.clone()).max_decoding_message_size(usize::MAX);
2296 let notification_client =
2297 NotificationServiceClient::new(channel.clone()).max_decoding_message_size(usize::MAX);
2298 let stream_client =
2299 StreamManagerServiceClient::new(channel.clone()).max_decoding_message_size(usize::MAX);
2300 let user_client = UserServiceClient::new(channel.clone());
2301 let scale_client =
2302 ScaleServiceClient::new(channel.clone()).max_decoding_message_size(usize::MAX);
2303 let backup_client = BackupServiceClient::new(channel.clone());
2304 let telemetry_client =
2305 TelemetryInfoServiceClient::new(channel.clone()).max_decoding_message_size(usize::MAX);
2306 let system_params_client = SystemParamsServiceClient::new(channel.clone());
2307 let session_params_client = SessionParamServiceClient::new(channel.clone());
2308 let serving_client = ServingServiceClient::new(channel.clone());
2309 let cloud_client = CloudServiceClient::new(channel.clone());
2310 let sink_coordinate_client = SinkCoordinationServiceClient::new(channel.clone())
2311 .max_decoding_message_size(usize::MAX);
2312 let event_log_client = EventLogServiceClient::new(channel.clone());
2313 let cluster_limit_client = ClusterLimitServiceClient::new(channel.clone());
2314 let hosted_iceberg_catalog_service_client =
2315 HostedIcebergCatalogServiceClient::new(channel.clone());
2316 let monitor_client = configured_monitor_service_client(MonitorServiceClient::new(channel));
2317
2318 GrpcMetaClientCore {
2319 cluster_client,
2320 meta_member_client,
2321 heartbeat_client,
2322 ddl_client,
2323 hummock_client,
2324 notification_client,
2325 stream_client,
2326 user_client,
2327 scale_client,
2328 backup_client,
2329 telemetry_client,
2330 system_params_client,
2331 session_params_client,
2332 serving_client,
2333 cloud_client,
2334 sink_coordinate_client,
2335 event_log_client,
2336 cluster_limit_client,
2337 hosted_iceberg_catalog_service_client,
2338 monitor_client,
2339 }
2340 }
2341}
2342
2343#[derive(Debug, Clone)]
2347struct GrpcMetaClient {
2348 member_monitor_event_sender: mpsc::Sender<Sender<Result<()>>>,
2349 core: Arc<RwLock<GrpcMetaClientCore>>,
2350}
2351
2352type MetaMemberClient = MetaMemberServiceClient<Channel>;
2353
2354struct MetaMemberGroup {
2355 members: LruCache<http::Uri, Option<MetaMemberClient>>,
2356}
2357
2358struct MetaMemberManagement {
2359 core_ref: Arc<RwLock<GrpcMetaClientCore>>,
2360 members: Either<MetaMemberClient, MetaMemberGroup>,
2361 current_leader: http::Uri,
2362 meta_config: Arc<MetaConfig>,
2363}
2364
2365impl MetaMemberManagement {
2366 const META_MEMBER_REFRESH_PERIOD: Duration = Duration::from_secs(5);
2367
2368 fn host_address_to_uri(addr: HostAddress) -> http::Uri {
2369 format!("http://{}:{}", addr.host, addr.port)
2370 .parse()
2371 .unwrap()
2372 }
2373
2374 async fn recreate_core(&self, channel: Channel) {
2375 let mut core = self.core_ref.write().await;
2376 *core = GrpcMetaClientCore::new(channel);
2377 }
2378
2379 async fn refresh_members(&mut self) -> Result<()> {
2380 let leader_addr = match self.members.as_mut() {
2381 Either::Left(client) => {
2382 let resp = client
2383 .to_owned()
2384 .members(MembersRequest {})
2385 .await
2386 .map_err(RpcError::from_meta_status)?;
2387 let resp = resp.into_inner();
2388 resp.members.into_iter().find(|member| member.is_leader)
2389 }
2390 Either::Right(member_group) => {
2391 let mut fetched_members = None;
2392
2393 for (addr, client) in &mut member_group.members {
2394 let members: Result<_> = try {
2395 let mut client = match client {
2396 Some(cached_client) => cached_client.to_owned(),
2397 None => {
2398 let endpoint = GrpcMetaClient::addr_to_endpoint(addr.clone());
2399 let channel = GrpcMetaClient::connect_to_endpoint(endpoint)
2400 .await
2401 .context("failed to create client")
2402 .map_err(RpcError::from)?;
2403 let new_client: MetaMemberClient =
2404 MetaMemberServiceClient::new(channel);
2405 *client = Some(new_client.clone());
2406
2407 new_client
2408 }
2409 };
2410
2411 let resp = client
2412 .members(MembersRequest {})
2413 .await
2414 .context("failed to fetch members")
2415 .map_err(RpcError::from)?;
2416
2417 resp.into_inner().members
2418 };
2419
2420 let fetched = members.is_ok();
2421 fetched_members = Some(members);
2422 if fetched {
2423 break;
2424 }
2425 }
2426
2427 let members = fetched_members
2428 .context("no member available in the list")?
2429 .context("could not refresh members")?;
2430
2431 let mut leader = None;
2433 for member in members {
2434 if member.is_leader {
2435 leader = Some(member.clone());
2436 }
2437
2438 let addr = Self::host_address_to_uri(member.address.unwrap());
2439 if !member_group.members.contains(&addr) {
2441 tracing::info!("new meta member joined: {}", addr);
2442 member_group.members.put(addr, None);
2443 }
2444 }
2445
2446 leader
2447 }
2448 };
2449
2450 if let Some(leader) = leader_addr {
2451 let discovered_leader = Self::host_address_to_uri(leader.address.unwrap());
2452
2453 if discovered_leader != self.current_leader {
2454 tracing::info!("new meta leader {} discovered", discovered_leader);
2455
2456 let retry_strategy = GrpcMetaClient::retry_strategy_to_bound(
2457 Duration::from_secs(self.meta_config.meta_leader_lease_secs),
2458 false,
2459 );
2460
2461 let channel = tokio_retry::Retry::spawn(retry_strategy, || async {
2462 let endpoint = GrpcMetaClient::addr_to_endpoint(discovered_leader.clone());
2463 GrpcMetaClient::connect_to_endpoint(endpoint).await
2464 })
2465 .await?;
2466
2467 self.recreate_core(channel).await;
2468 self.current_leader = discovered_leader;
2469 }
2470 }
2471
2472 Ok(())
2473 }
2474}
2475
2476impl GrpcMetaClient {
2477 const ENDPOINT_KEEP_ALIVE_INTERVAL_SEC: u64 = 60;
2479 const ENDPOINT_KEEP_ALIVE_TIMEOUT_SEC: u64 = 60;
2481 const INIT_RETRY_BASE_INTERVAL_MS: u64 = 10;
2483 const INIT_RETRY_MAX_INTERVAL_MS: u64 = 2000;
2485
2486 fn start_meta_member_monitor(
2487 &self,
2488 init_leader_addr: http::Uri,
2489 members: Either<MetaMemberClient, MetaMemberGroup>,
2490 force_refresh_receiver: Receiver<Sender<Result<()>>>,
2491 meta_config: Arc<MetaConfig>,
2492 ) -> Result<()> {
2493 let core_ref: Arc<RwLock<GrpcMetaClientCore>> = self.core.clone();
2494 let current_leader = init_leader_addr;
2495
2496 let enable_period_tick = matches!(members, Either::Right(_));
2497
2498 let member_management = MetaMemberManagement {
2499 core_ref,
2500 members,
2501 current_leader,
2502 meta_config,
2503 };
2504
2505 let mut force_refresh_receiver = force_refresh_receiver;
2506
2507 tokio::spawn(async move {
2508 let mut member_management = member_management;
2509 let mut ticker = time::interval(MetaMemberManagement::META_MEMBER_REFRESH_PERIOD);
2510
2511 loop {
2512 let event: Option<Sender<Result<()>>> = if enable_period_tick {
2513 tokio::select! {
2514 _ = ticker.tick() => None,
2515 result_sender = force_refresh_receiver.recv() => {
2516 if result_sender.is_none() {
2517 break;
2518 }
2519
2520 result_sender
2521 },
2522 }
2523 } else {
2524 let result_sender = force_refresh_receiver.recv().await;
2525
2526 if result_sender.is_none() {
2527 break;
2528 }
2529
2530 result_sender
2531 };
2532
2533 let tick_result = member_management.refresh_members().await;
2534 if let Err(e) = tick_result.as_ref() {
2535 tracing::warn!(error = %e.as_report(), "refresh meta member client failed");
2536 }
2537
2538 if let Some(sender) = event {
2539 let _resp = sender.send(tick_result);
2541 }
2542 }
2543 });
2544
2545 Ok(())
2546 }
2547
2548 async fn force_refresh_leader(&self) -> Result<()> {
2549 let (sender, receiver) = oneshot::channel();
2550
2551 self.member_monitor_event_sender
2552 .send(sender)
2553 .await
2554 .map_err(|e| anyhow!(e))?;
2555
2556 receiver.await.map_err(|e| anyhow!(e))?
2557 }
2558
2559 pub async fn new(strategy: &MetaAddressStrategy, config: Arc<MetaConfig>) -> Result<Self> {
2561 let (channel, addr) = match strategy {
2562 MetaAddressStrategy::LoadBalance(addr) => {
2563 Self::try_build_rpc_channel(vec![addr.clone()]).await
2564 }
2565 MetaAddressStrategy::List(addrs) => Self::try_build_rpc_channel(addrs.clone()).await,
2566 }?;
2567 let (force_refresh_sender, force_refresh_receiver) = mpsc::channel(1);
2568 let client = GrpcMetaClient {
2569 member_monitor_event_sender: force_refresh_sender,
2570 core: Arc::new(RwLock::new(GrpcMetaClientCore::new(channel))),
2571 };
2572
2573 let meta_member_client = client.core.read().await.meta_member_client.clone();
2574 let members = match strategy {
2575 MetaAddressStrategy::LoadBalance(_) => Either::Left(meta_member_client),
2576 MetaAddressStrategy::List(addrs) => {
2577 let mut members = LruCache::new(20.try_into().unwrap());
2578 for addr in addrs {
2579 members.put(addr.clone(), None);
2580 }
2581 members.put(addr.clone(), Some(meta_member_client));
2582
2583 Either::Right(MetaMemberGroup { members })
2584 }
2585 };
2586
2587 client.start_meta_member_monitor(addr, members, force_refresh_receiver, config.clone())?;
2588
2589 client.force_refresh_leader().await?;
2590
2591 Ok(client)
2592 }
2593
2594 fn addr_to_endpoint(addr: http::Uri) -> Endpoint {
2595 Endpoint::from(addr).initial_connection_window_size(MAX_CONNECTION_WINDOW_SIZE)
2596 }
2597
2598 pub(crate) async fn try_build_rpc_channel(
2599 addrs: impl IntoIterator<Item = http::Uri>,
2600 ) -> Result<(Channel, http::Uri)> {
2601 let endpoints: Vec<_> = addrs
2602 .into_iter()
2603 .map(|addr| (Self::addr_to_endpoint(addr.clone()), addr))
2604 .collect();
2605
2606 let mut last_error = None;
2607
2608 for (endpoint, addr) in endpoints {
2609 match Self::connect_to_endpoint(endpoint).await {
2610 Ok(channel) => {
2611 tracing::info!("Connect to meta server {} successfully", addr);
2612 return Ok((channel, addr));
2613 }
2614 Err(e) => {
2615 tracing::warn!(
2616 error = %e.as_report(),
2617 "Failed to connect to meta server {}, trying again",
2618 addr,
2619 );
2620 last_error = Some(e);
2621 }
2622 }
2623 }
2624
2625 if let Some(last_error) = last_error {
2626 Err(anyhow::anyhow!(last_error)
2627 .context("failed to connect to all meta servers")
2628 .into())
2629 } else {
2630 bail!("no meta server address provided")
2631 }
2632 }
2633
2634 async fn connect_to_endpoint(endpoint: Endpoint) -> Result<Channel> {
2635 let channel = endpoint
2636 .http2_keep_alive_interval(Duration::from_secs(Self::ENDPOINT_KEEP_ALIVE_INTERVAL_SEC))
2637 .keep_alive_timeout(Duration::from_secs(Self::ENDPOINT_KEEP_ALIVE_TIMEOUT_SEC))
2638 .connect_timeout(Duration::from_secs(5))
2639 .monitored_connect("grpc-meta-client", Default::default())
2640 .await?
2641 .wrapped();
2642
2643 Ok(channel)
2644 }
2645
2646 pub(crate) fn retry_strategy_to_bound(
2647 high_bound: Duration,
2648 exceed: bool,
2649 ) -> impl Iterator<Item = Duration> {
2650 let iter = ExponentialBackoff::from_millis(Self::INIT_RETRY_BASE_INTERVAL_MS)
2651 .max_delay(Duration::from_millis(Self::INIT_RETRY_MAX_INTERVAL_MS))
2652 .map(jitter);
2653
2654 let mut sum = Duration::default();
2655
2656 iter.take_while(move |duration| {
2657 sum += *duration;
2658
2659 if exceed {
2660 sum < high_bound + *duration
2661 } else {
2662 sum < high_bound
2663 }
2664 })
2665 }
2666}
2667
2668macro_rules! for_all_meta_rpc {
2669 ($macro:ident) => {
2670 $macro! {
2671 { cluster_client, add_worker_node, AddWorkerNodeRequest, AddWorkerNodeResponse }
2672 ,{ cluster_client, activate_worker_node, ActivateWorkerNodeRequest, ActivateWorkerNodeResponse }
2673 ,{ cluster_client, delete_worker_node, DeleteWorkerNodeRequest, DeleteWorkerNodeResponse }
2674 ,{ cluster_client, list_all_nodes, ListAllNodesRequest, ListAllNodesResponse }
2675 ,{ cluster_client, get_cluster_recovery_status, GetClusterRecoveryStatusRequest, GetClusterRecoveryStatusResponse }
2676 ,{ cluster_client, get_meta_store_info, GetMetaStoreInfoRequest, GetMetaStoreInfoResponse }
2677 ,{ heartbeat_client, heartbeat, HeartbeatRequest, HeartbeatResponse }
2678 ,{ stream_client, flush, FlushRequest, FlushResponse }
2679 ,{ stream_client, pause, PauseRequest, PauseResponse }
2680 ,{ stream_client, resume, ResumeRequest, ResumeResponse }
2681 ,{ stream_client, apply_throttle, ApplyThrottleRequest, ApplyThrottleResponse }
2682 ,{ stream_client, cancel_creating_jobs, CancelCreatingJobsRequest, CancelCreatingJobsResponse }
2683 ,{ stream_client, list_table_fragments, ListTableFragmentsRequest, ListTableFragmentsResponse }
2684 ,{ stream_client, list_streaming_job_states, ListStreamingJobStatesRequest, ListStreamingJobStatesResponse }
2685 ,{ stream_client, list_fragment_distribution, ListFragmentDistributionRequest, ListFragmentDistributionResponse }
2686 ,{ stream_client, list_creating_fragment_distribution, ListCreatingFragmentDistributionRequest, ListCreatingFragmentDistributionResponse }
2687 ,{ stream_client, list_sink_log_store_tables, ListSinkLogStoreTablesRequest, ListSinkLogStoreTablesResponse }
2688 ,{ stream_client, list_actor_states, ListActorStatesRequest, ListActorStatesResponse }
2689 ,{ stream_client, list_actor_splits, ListActorSplitsRequest, ListActorSplitsResponse }
2690 ,{ stream_client, recover, RecoverRequest, RecoverResponse }
2691 ,{ stream_client, list_rate_limits, ListRateLimitsRequest, ListRateLimitsResponse }
2692 ,{ stream_client, list_cdc_progress, ListCdcProgressRequest, ListCdcProgressResponse }
2693 ,{ stream_client, list_refresh_table_states, ListRefreshTableStatesRequest, ListRefreshTableStatesResponse }
2694 ,{ stream_client, list_iceberg_compaction_status, ListIcebergCompactionStatusRequest, ListIcebergCompactionStatusResponse }
2695 ,{ stream_client, alter_connector_props, AlterConnectorPropsRequest, AlterConnectorPropsResponse }
2696 ,{ stream_client, alter_source_properties_safe, AlterSourcePropertiesSafeRequest, AlterSourcePropertiesSafeResponse }
2697 ,{ stream_client, reset_source_splits, ResetSourceSplitsRequest, ResetSourceSplitsResponse }
2698 ,{ stream_client, inject_source_offsets, InjectSourceOffsetsRequest, InjectSourceOffsetsResponse }
2699 ,{ stream_client, get_fragment_by_id, GetFragmentByIdRequest, GetFragmentByIdResponse }
2700 ,{ stream_client, get_fragment_vnodes, GetFragmentVnodesRequest, GetFragmentVnodesResponse }
2701 ,{ stream_client, get_actor_vnodes, GetActorVnodesRequest, GetActorVnodesResponse }
2702 ,{ stream_client, set_sync_log_store_aligned, SetSyncLogStoreAlignedRequest, SetSyncLogStoreAlignedResponse }
2703 ,{ stream_client, refresh, RefreshRequest, RefreshResponse }
2704 ,{ stream_client, list_unmigrated_tables, ListUnmigratedTablesRequest, ListUnmigratedTablesResponse }
2705 ,{ ddl_client, create_table, CreateTableRequest, CreateTableResponse }
2706 ,{ ddl_client, alter_name, AlterNameRequest, AlterNameResponse }
2707 ,{ ddl_client, alter_owner, AlterOwnerRequest, AlterOwnerResponse }
2708 ,{ ddl_client, alter_subscription_retention, AlterSubscriptionRetentionRequest, AlterSubscriptionRetentionResponse }
2709 ,{ ddl_client, alter_set_schema, AlterSetSchemaRequest, AlterSetSchemaResponse }
2710 ,{ ddl_client, alter_parallelism, AlterParallelismRequest, AlterParallelismResponse }
2711 ,{ ddl_client, alter_backfill_parallelism, AlterBackfillParallelismRequest, AlterBackfillParallelismResponse }
2712 ,{ ddl_client, alter_streaming_job_config, AlterStreamingJobConfigRequest, AlterStreamingJobConfigResponse }
2713 ,{ ddl_client, alter_fragment_parallelism, AlterFragmentParallelismRequest, AlterFragmentParallelismResponse }
2714 ,{ ddl_client, alter_cdc_table_backfill_parallelism, AlterCdcTableBackfillParallelismRequest, AlterCdcTableBackfillParallelismResponse }
2715 ,{ ddl_client, alter_resource_group, AlterResourceGroupRequest, AlterResourceGroupResponse }
2716 ,{ ddl_client, alter_database_resource_group, AlterDatabaseResourceGroupRequest, AlterDatabaseResourceGroupResponse }
2717 ,{ ddl_client, alter_database_param, AlterDatabaseParamRequest, AlterDatabaseParamResponse }
2718 ,{ ddl_client, create_materialized_view, CreateMaterializedViewRequest, CreateMaterializedViewResponse }
2719 ,{ ddl_client, create_view, CreateViewRequest, CreateViewResponse }
2720 ,{ ddl_client, create_source, CreateSourceRequest, CreateSourceResponse }
2721 ,{ ddl_client, create_sink, CreateSinkRequest, CreateSinkResponse }
2722 ,{ ddl_client, create_subscription, CreateSubscriptionRequest, CreateSubscriptionResponse }
2723 ,{ ddl_client, create_schema, CreateSchemaRequest, CreateSchemaResponse }
2724 ,{ ddl_client, create_database, CreateDatabaseRequest, CreateDatabaseResponse }
2725 ,{ ddl_client, create_secret, CreateSecretRequest, CreateSecretResponse }
2726 ,{ ddl_client, create_index, CreateIndexRequest, CreateIndexResponse }
2727 ,{ ddl_client, create_function, CreateFunctionRequest, CreateFunctionResponse }
2728 ,{ ddl_client, drop_table, DropTableRequest, DropTableResponse }
2729 ,{ ddl_client, drop_materialized_view, DropMaterializedViewRequest, DropMaterializedViewResponse }
2730 ,{ ddl_client, drop_view, DropViewRequest, DropViewResponse }
2731 ,{ ddl_client, drop_source, DropSourceRequest, DropSourceResponse }
2732 ,{ ddl_client, reset_source, ResetSourceRequest, ResetSourceResponse }
2733 ,{ ddl_client, drop_secret, DropSecretRequest, DropSecretResponse}
2734 ,{ ddl_client, drop_sink, DropSinkRequest, DropSinkResponse }
2735 ,{ ddl_client, drop_subscription, DropSubscriptionRequest, DropSubscriptionResponse }
2736 ,{ ddl_client, drop_database, DropDatabaseRequest, DropDatabaseResponse }
2737 ,{ ddl_client, drop_schema, DropSchemaRequest, DropSchemaResponse }
2738 ,{ ddl_client, drop_index, DropIndexRequest, DropIndexResponse }
2739 ,{ ddl_client, drop_function, DropFunctionRequest, DropFunctionResponse }
2740 ,{ ddl_client, replace_job_plan, ReplaceJobPlanRequest, ReplaceJobPlanResponse }
2741 ,{ ddl_client, alter_source, AlterSourceRequest, AlterSourceResponse }
2742 ,{ ddl_client, risectl_list_state_tables, RisectlListStateTablesRequest, RisectlListStateTablesResponse }
2743 ,{ ddl_client, risectl_resume_backfill, RisectlResumeBackfillRequest, RisectlResumeBackfillResponse }
2744 ,{ ddl_client, get_ddl_progress, GetDdlProgressRequest, GetDdlProgressResponse }
2745 ,{ ddl_client, create_connection, CreateConnectionRequest, CreateConnectionResponse }
2746 ,{ ddl_client, list_connections, ListConnectionsRequest, ListConnectionsResponse }
2747 ,{ ddl_client, drop_connection, DropConnectionRequest, DropConnectionResponse }
2748 ,{ ddl_client, comment_on, CommentOnRequest, CommentOnResponse }
2749 ,{ ddl_client, get_tables, GetTablesRequest, GetTablesResponse }
2750 ,{ ddl_client, wait, WaitRequest, WaitResponse }
2751 ,{ ddl_client, auto_schema_change, AutoSchemaChangeRequest, AutoSchemaChangeResponse }
2752 ,{ ddl_client, alter_swap_rename, AlterSwapRenameRequest, AlterSwapRenameResponse }
2753 ,{ ddl_client, alter_secret, AlterSecretRequest, AlterSecretResponse }
2754 ,{ ddl_client, compact_iceberg_table, CompactIcebergTableRequest, CompactIcebergTableResponse }
2755 ,{ ddl_client, expire_iceberg_table_snapshots, ExpireIcebergTableSnapshotsRequest, ExpireIcebergTableSnapshotsResponse }
2756 ,{ ddl_client, create_iceberg_table, CreateIcebergTableRequest, CreateIcebergTableResponse }
2757 ,{ hummock_client, unpin_version_before, UnpinVersionBeforeRequest, UnpinVersionBeforeResponse }
2758 ,{ hummock_client, get_current_version, GetCurrentVersionRequest, GetCurrentVersionResponse }
2759 ,{ hummock_client, replay_version_delta, ReplayVersionDeltaRequest, ReplayVersionDeltaResponse }
2760 ,{ hummock_client, list_version_deltas, ListVersionDeltasRequest, ListVersionDeltasResponse }
2761 ,{ hummock_client, get_assigned_compact_task_num, GetAssignedCompactTaskNumRequest, GetAssignedCompactTaskNumResponse }
2762 ,{ hummock_client, trigger_compaction_deterministic, TriggerCompactionDeterministicRequest, TriggerCompactionDeterministicResponse }
2763 ,{ hummock_client, disable_commit_epoch, DisableCommitEpochRequest, DisableCommitEpochResponse }
2764 ,{ hummock_client, get_new_object_ids, GetNewObjectIdsRequest, GetNewObjectIdsResponse }
2765 ,{ hummock_client, trigger_manual_compaction, TriggerManualCompactionRequest, TriggerManualCompactionResponse }
2766 ,{ hummock_client, trigger_full_gc, TriggerFullGcRequest, TriggerFullGcResponse }
2767 ,{ hummock_client, rise_ctl_get_pinned_versions_summary, RiseCtlGetPinnedVersionsSummaryRequest, RiseCtlGetPinnedVersionsSummaryResponse }
2768 ,{ hummock_client, rise_ctl_list_compaction_group, RiseCtlListCompactionGroupRequest, RiseCtlListCompactionGroupResponse }
2769 ,{ hummock_client, rise_ctl_update_compaction_config, RiseCtlUpdateCompactionConfigRequest, RiseCtlUpdateCompactionConfigResponse }
2770 ,{ hummock_client, rise_ctl_get_checkpoint_version, RiseCtlGetCheckpointVersionRequest, RiseCtlGetCheckpointVersionResponse }
2771 ,{ hummock_client, rise_ctl_pause_version_checkpoint, RiseCtlPauseVersionCheckpointRequest, RiseCtlPauseVersionCheckpointResponse }
2772 ,{ hummock_client, rise_ctl_resume_version_checkpoint, RiseCtlResumeVersionCheckpointRequest, RiseCtlResumeVersionCheckpointResponse }
2773 ,{ hummock_client, init_metadata_for_replay, InitMetadataForReplayRequest, InitMetadataForReplayResponse }
2774 ,{ hummock_client, split_compaction_group, SplitCompactionGroupRequest, SplitCompactionGroupResponse }
2775 ,{ hummock_client, rise_ctl_list_compaction_status, RiseCtlListCompactionStatusRequest, RiseCtlListCompactionStatusResponse }
2776 ,{ hummock_client, get_compaction_score, GetCompactionScoreRequest, GetCompactionScoreResponse }
2777 ,{ hummock_client, rise_ctl_rebuild_table_stats, RiseCtlRebuildTableStatsRequest, RiseCtlRebuildTableStatsResponse }
2778 ,{ hummock_client, subscribe_compaction_event, impl tonic::IntoStreamingRequest<Message = SubscribeCompactionEventRequest>, Streaming<SubscribeCompactionEventResponse> }
2779 ,{ hummock_client, subscribe_iceberg_compaction_event, impl tonic::IntoStreamingRequest<Message = SubscribeIcebergCompactionEventRequest>, Streaming<SubscribeIcebergCompactionEventResponse> }
2780 ,{ hummock_client, list_branched_object, ListBranchedObjectRequest, ListBranchedObjectResponse }
2781 ,{ hummock_client, list_active_write_limit, ListActiveWriteLimitRequest, ListActiveWriteLimitResponse }
2782 ,{ hummock_client, list_hummock_meta_config, ListHummockMetaConfigRequest, ListHummockMetaConfigResponse }
2783 ,{ hummock_client, list_compact_task_assignment, ListCompactTaskAssignmentRequest, ListCompactTaskAssignmentResponse }
2784 ,{ hummock_client, list_compact_task_progress, ListCompactTaskProgressRequest, ListCompactTaskProgressResponse }
2785 ,{ hummock_client, cancel_compact_task, CancelCompactTaskRequest, CancelCompactTaskResponse}
2786 ,{ hummock_client, get_version_by_epoch, GetVersionByEpochRequest, GetVersionByEpochResponse }
2787 ,{ hummock_client, merge_compaction_group, MergeCompactionGroupRequest, MergeCompactionGroupResponse }
2788 ,{ hummock_client, get_table_change_logs, GetTableChangeLogsRequest, GetTableChangeLogsResponse }
2789 ,{ user_client, create_user, CreateUserRequest, CreateUserResponse }
2790 ,{ user_client, update_user, UpdateUserRequest, UpdateUserResponse }
2791 ,{ user_client, drop_user, DropUserRequest, DropUserResponse }
2792 ,{ user_client, grant_privilege, GrantPrivilegeRequest, GrantPrivilegeResponse }
2793 ,{ user_client, revoke_privilege, RevokePrivilegeRequest, RevokePrivilegeResponse }
2794 ,{ user_client, alter_default_privilege, AlterDefaultPrivilegeRequest, AlterDefaultPrivilegeResponse }
2795 ,{ scale_client, get_cluster_info, GetClusterInfoRequest, GetClusterInfoResponse }
2796 ,{ scale_client, reschedule, RescheduleRequest, RescheduleResponse }
2797 ,{ notification_client, subscribe, SubscribeRequest, Streaming<SubscribeResponse> }
2798 ,{ backup_client, backup_meta, BackupMetaRequest, BackupMetaResponse }
2799 ,{ backup_client, get_backup_job_status, GetBackupJobStatusRequest, GetBackupJobStatusResponse }
2800 ,{ backup_client, delete_meta_snapshot, DeleteMetaSnapshotRequest, DeleteMetaSnapshotResponse}
2801 ,{ backup_client, get_meta_snapshot_manifest, GetMetaSnapshotManifestRequest, GetMetaSnapshotManifestResponse}
2802 ,{ telemetry_client, get_telemetry_info, GetTelemetryInfoRequest, TelemetryInfoResponse}
2803 ,{ system_params_client, get_system_params, GetSystemParamsRequest, GetSystemParamsResponse }
2804 ,{ system_params_client, set_system_param, SetSystemParamRequest, SetSystemParamResponse }
2805 ,{ session_params_client, get_session_params, GetSessionParamsRequest, GetSessionParamsResponse }
2806 ,{ session_params_client, set_session_param, SetSessionParamRequest, SetSessionParamResponse }
2807 ,{ serving_client, get_serving_vnode_mappings, GetServingVnodeMappingsRequest, GetServingVnodeMappingsResponse }
2808 ,{ cloud_client, rw_cloud_validate_source, RwCloudValidateSourceRequest, RwCloudValidateSourceResponse }
2809 ,{ event_log_client, list_event_log, ListEventLogRequest, ListEventLogResponse }
2810 ,{ event_log_client, add_event_log, AddEventLogRequest, AddEventLogResponse }
2811 ,{ cluster_limit_client, get_cluster_limits, GetClusterLimitsRequest, GetClusterLimitsResponse }
2812 ,{ hosted_iceberg_catalog_service_client, list_iceberg_tables, ListIcebergTablesRequest, ListIcebergTablesResponse }
2813 ,{ monitor_client, stack_trace, StackTraceRequest, StackTraceResponse }
2814 }
2815 };
2816}
2817
2818impl GrpcMetaClient {
2819 async fn refresh_client_if_needed(&self, code: Code) {
2820 if matches!(
2821 code,
2822 Code::Unknown | Code::Unimplemented | Code::Unavailable
2823 ) {
2824 tracing::debug!("matching tonic code {}", code);
2825 let (result_sender, result_receiver) = oneshot::channel();
2826 if self
2827 .member_monitor_event_sender
2828 .try_send(result_sender)
2829 .is_ok()
2830 {
2831 if let Ok(Err(e)) = result_receiver.await {
2832 tracing::warn!(error = %e.as_report(), "force refresh meta client failed");
2833 }
2834 } else {
2835 tracing::debug!("skipping the current refresh, somewhere else is already doing it")
2836 }
2837 }
2838 }
2839}
2840
2841impl GrpcMetaClient {
2842 for_all_meta_rpc! { meta_rpc_client_method_impl }
2843}