mod builder;
mod config;
mod grpc_client;
mod pool;
mod proto;
mod scoped_timer;
mod utils;
pub use builder::*;
pub use config::*;
pub use d_engine_core::client::ErrorCode;
pub use d_engine_core::client::{ClientApi, ClientApiError, ClientApiResult};
pub use grpc_client::*;
pub(crate) use pool::*;
pub mod protocol {
pub use d_engine_core::client::KvEntry;
pub use d_engine_core::config::ReadConsistencyPolicy;
pub use d_engine_proto::client::WatchEventType;
pub use d_engine_proto::client::WatchRequest;
pub use d_engine_proto::client::WatchResponse;
pub use d_engine_proto::client::WriteCommand;
}
pub mod cluster_types {
pub use d_engine_proto::common::NodeStatus;
pub use d_engine_proto::server::cluster::NodeMeta;
}
pub(crate) use proto::*;
#[cfg(test)]
mod error_test;
#[cfg(test)]
mod grpc_client_test;
#[cfg(test)]
mod mock_rpc;
#[cfg(test)]
mod mock_rpc_service;
#[cfg(test)]
mod pool_test;
#[cfg(test)]
mod utils_test;
#[derive(Clone)]
pub struct Client {
inner: std::sync::Arc<GrpcClient>,
}
#[derive(Clone)]
pub(crate) struct ClientInner {
pub(crate) pool: ConnectionPool,
pub(crate) client_id: u32,
pub(crate) config: ClientConfig,
pub(crate) endpoints: Vec<String>,
}
impl std::ops::Deref for Client {
type Target = GrpcClient;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Client {
pub fn builder(endpoints: Vec<String>) -> ClientBuilder {
assert!(!endpoints.is_empty(), "At least one endpoint required");
ClientBuilder::new(endpoints)
}
pub async fn refresh(
&self,
new_endpoints: Option<Vec<String>>,
) -> std::result::Result<(), ClientApiError> {
let old_inner = self.inner.client_inner.load();
let config = old_inner.config.clone();
let endpoints = new_endpoints.unwrap_or(old_inner.endpoints.clone());
let new_pool = ConnectionPool::create(endpoints.clone(), config.clone()).await?;
let new_inner = std::sync::Arc::new(ClientInner {
pool: new_pool,
client_id: old_inner.client_id,
config,
endpoints,
});
self.inner.client_inner.store(new_inner);
Ok(())
}
}