use crate::cluster::{ClusterState, NodeRef};
use crate::frame::response::result::TableSpec;
use crate::frame::types;
use crate::routing::NodeLocationPreference;
use crate::{
errors::RequestAttemptError,
routing::{Shard, Token},
};
use std::time::Duration;
mod default;
mod plan;
mod single_target;
pub use default::{DefaultPolicy, DefaultPolicyBuilder, LatencyAwarenessBuilder};
pub use plan::Plan;
pub use single_target::{NodeIdentifier, SingleTargetLoadBalancingPolicy};
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct RoutingInfo<'a> {
pub consistency: types::Consistency,
pub serial_consistency: Option<types::SerialConsistency>,
pub token: Option<Token>,
pub table: Option<&'a TableSpec<'a>>,
pub is_confirmed_lwt: bool,
pub node_location_preference: &'a NodeLocationPreference,
}
impl Default for RoutingInfo<'_> {
fn default() -> Self {
Self {
consistency: types::Consistency::default(),
serial_consistency: None,
token: None,
table: None,
is_confirmed_lwt: false,
node_location_preference: &NodeLocationPreference::Any,
}
}
}
impl RoutingInfo<'_> {
pub fn should_route_as_lwt(&self) -> bool {
self.is_confirmed_lwt
|| matches!(
self.consistency,
types::Consistency::Serial | types::Consistency::LocalSerial
)
}
}
pub type FallbackPlan<'a> =
Box<dyn Iterator<Item = (NodeRef<'a>, Option<Shard>)> + Send + Sync + 'a>;
pub trait LoadBalancingPolicy: Send + Sync + std::fmt::Debug {
fn pick<'a>(
&'a self,
request: &'a RoutingInfo,
cluster: &'a ClusterState,
) -> Option<(NodeRef<'a>, Option<Shard>)>;
fn fallback<'a>(
&'a self,
request: &'a RoutingInfo,
cluster: &'a ClusterState,
) -> FallbackPlan<'a>;
fn on_request_success(&self, _request: &RoutingInfo, _latency: Duration, _node: NodeRef<'_>) {}
fn on_request_failure(
&self,
_request: &RoutingInfo,
_latency: Duration,
_node: NodeRef<'_>,
_error: &RequestAttemptError,
) {
}
fn name(&self) -> String;
}