use core::marker::PhantomData;
use core::time::Duration;
use std::sync::Arc;
use crate::crypto::hash::{Digest, Sha3_256};
use crate::policy::GatePolicy;
use crate::transport::client::pool::PoolConfig;
use crate::transport::policy::{RestartExponentialBackoff, RestartPolicy};
use super::{
ClusterConf, ClusterTlsConfig, HeartbeatCallback, HeartbeatConf, PheromoneConf, DEFAULT_HEARTBEAT_INTERVAL_SECS,
DEFAULT_HEARTBEAT_TIMEOUT_SECS, DEFAULT_MAX_CONCURRENT, DEFAULT_MAX_FAILURES,
};
use crate::colony::common::LeastLoaded;
use crate::colony::hive::LoadBalancer;
pub struct HeartbeatConfBuilder {
interval: Duration,
timeout: Duration,
retry_policy: Option<Arc<dyn RestartPolicy + Send + Sync>>,
max_concurrent: usize,
max_failures: u32,
on_heartbeat: Option<HeartbeatCallback>,
}
impl Default for HeartbeatConfBuilder {
fn default() -> Self {
Self {
interval: Duration::from_secs(DEFAULT_HEARTBEAT_INTERVAL_SECS),
timeout: Duration::from_secs(DEFAULT_HEARTBEAT_TIMEOUT_SECS),
retry_policy: None,
max_concurrent: DEFAULT_MAX_CONCURRENT,
max_failures: DEFAULT_MAX_FAILURES,
on_heartbeat: None,
}
}
}
impl HeartbeatConf {
pub fn builder() -> HeartbeatConfBuilder {
HeartbeatConfBuilder::default()
}
}
impl HeartbeatConfBuilder {
pub fn with_interval(mut self, interval: Duration) -> Self {
self.interval = interval;
self
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
pub fn with_max_failures(mut self, max: u32) -> Self {
self.max_failures = max;
self
}
pub fn with_max_concurrent(mut self, max: usize) -> Self {
self.max_concurrent = max;
self
}
pub fn with_callback(mut self, callback: HeartbeatCallback) -> Self {
self.on_heartbeat = Some(callback);
self
}
pub fn with_retry_policy(mut self, policy: Arc<dyn RestartPolicy + Send + Sync>) -> Self {
self.retry_policy = Some(policy);
self
}
pub fn build(self) -> HeartbeatConf {
HeartbeatConf {
interval: self.interval,
timeout: self.timeout,
retry_policy: self.retry_policy,
max_concurrent: self.max_concurrent,
max_failures: self.max_failures,
on_heartbeat: self.on_heartbeat,
}
}
}
#[cfg(feature = "x509")]
pub struct ClusterConfBuilder<L: LoadBalancer = LeastLoaded, D: Digest = Sha3_256> {
load_balancer: L,
heartbeat: HeartbeatConf,
pheromone: PheromoneConf,
policies: Vec<Arc<dyn GatePolicy + Send + Sync>>,
pool_config: PoolConfig,
retry_policy: Arc<dyn RestartPolicy + Send + Sync>,
tls: ClusterTlsConfig,
_digest: PhantomData<D>,
}
#[cfg(feature = "x509")]
impl ClusterConf {
pub fn builder(tls: ClusterTlsConfig) -> ClusterConfBuilder {
ClusterConfBuilder {
load_balancer: LeastLoaded,
heartbeat: HeartbeatConf::default(),
pheromone: PheromoneConf::default(),
policies: Vec::new(),
pool_config: PoolConfig::default(),
retry_policy: Arc::new(RestartExponentialBackoff::default()),
tls,
_digest: PhantomData,
}
}
}
#[cfg(feature = "x509")]
impl<L: LoadBalancer, D: Digest> ClusterConfBuilder<L, D> {
pub fn with_heartbeat_config(mut self, config: HeartbeatConf) -> Self {
self.heartbeat = config;
self
}
pub fn with_pheromone_config(mut self, config: PheromoneConf) -> Self {
self.pheromone = config;
self
}
pub fn with_load_balancer<L2: LoadBalancer>(self, load_balancer: L2) -> ClusterConfBuilder<L2, D> {
ClusterConfBuilder {
load_balancer,
heartbeat: self.heartbeat,
pheromone: self.pheromone,
policies: self.policies,
pool_config: self.pool_config,
retry_policy: self.retry_policy,
tls: self.tls,
_digest: PhantomData,
}
}
pub fn with_gate_policy(mut self, policy: Arc<dyn GatePolicy + Send + Sync>) -> Self {
self.policies.push(policy);
self
}
pub fn with_pool_config(mut self, config: PoolConfig) -> Self {
self.pool_config = config;
self
}
pub fn with_retry_policy(mut self, policy: Arc<dyn RestartPolicy + Send + Sync>) -> Self {
self.retry_policy = policy;
self
}
pub fn build(self) -> ClusterConf<L, D> {
ClusterConf {
load_balancer: self.load_balancer,
heartbeat: self.heartbeat,
pheromone: self.pheromone,
policies: self.policies,
pool_config: self.pool_config,
retry_policy: self.retry_policy,
tls: self.tls,
_digest: PhantomData,
}
}
}