goosefs_sdk/client/
worker_manager.rs1use std::sync::Arc;
26
27use tonic::service::interceptor::InterceptedService;
28use tonic::transport::Channel;
29use tracing::{debug, instrument};
30
31use crate::auth::{ChannelAuthenticator, ChannelIdInterceptor, SaslStreamGuard};
32use crate::client::master_inquire::{create_master_inquire_client, MasterInquireClient};
33use crate::config::GoosefsConfig;
34use crate::error::{Error, Result};
35use crate::proto::grpc::block::{
36 worker_manager_master_client_service_client::WorkerManagerMasterClientServiceClient,
37 GetWorkerInfoListPOptions, WorkerInfo,
38};
39
40type AuthenticatedWorkerMgrClient =
42 WorkerManagerMasterClientServiceClient<InterceptedService<Channel, ChannelIdInterceptor>>;
43
44#[derive(Clone)]
48pub struct WorkerManagerClient {
49 inner: AuthenticatedWorkerMgrClient,
50 _sasl_guard: Arc<Option<SaslStreamGuard>>,
52}
53
54impl WorkerManagerClient {
55 pub async fn connect(config: &GoosefsConfig) -> Result<Self> {
59 let inquire_client = create_master_inquire_client(config);
60 Self::connect_with_inquire(config, inquire_client).await
61 }
62
63 pub async fn connect_with_inquire(
68 config: &GoosefsConfig,
69 inquire_client: Arc<dyn MasterInquireClient>,
70 ) -> Result<Self> {
71 let primary_addr = inquire_client.get_primary_rpc_address().await?;
72 let endpoint_uri = format!("http://{}", primary_addr);
73
74 let endpoint = Channel::from_shared(endpoint_uri)
75 .map_err(|e| Error::ConfigError {
76 message: format!("invalid master endpoint: {}", e),
77 })?
78 .connect_timeout(config.connect_timeout)
79 .timeout(config.request_timeout);
80
81 let channel = endpoint.connect().await?;
82
83 let authenticator =
85 ChannelAuthenticator::new(config.auth_type, config.auth_username.clone(), None)
86 .with_auth_timeout(config.auth_timeout);
87
88 let mut auth_channel = authenticator.authenticate(channel).await?;
89 let sasl_guard = auth_channel.take_sasl_guard();
90 debug!(addr = %primary_addr, auth_type = %config.auth_type, "connected to WorkerManagerMasterClientService");
91
92 Ok(Self {
93 inner: WorkerManagerMasterClientServiceClient::new(auth_channel.channel),
94 _sasl_guard: Arc::new(sasl_guard),
95 })
96 }
97
98 pub fn from_channel(channel: Channel) -> Self {
102 let interceptor = ChannelIdInterceptor::new("test-no-auth".to_string());
103 let intercepted = InterceptedService::new(channel, interceptor);
104 Self {
105 inner: WorkerManagerMasterClientServiceClient::new(intercepted),
106 _sasl_guard: Arc::new(None),
107 }
108 }
109
110 #[instrument(skip(self))]
112 pub async fn get_worker_info_list(&self) -> Result<Vec<WorkerInfo>> {
113 let req = GetWorkerInfoListPOptions {};
114
115 let resp = self.inner.clone().get_worker_info_list(req).await?;
116
117 Ok(resp.into_inner().worker_infos)
118 }
119}