Skip to main content

ClusterDispatcher

Struct ClusterDispatcher 

Source
pub struct ClusterDispatcher { /* private fields */ }
Expand description

Cluster-aware dispatcher.

Implementations§

Source§

impl ClusterDispatcher

Source

pub fn new(pool: Arc<ServerPool>) -> Self

Wrap a ServerPool in a dispatcher.

§Examples
let pool = Arc::new(ServerPool::new(cfg, vec![local]));
let disp = ClusterDispatcher::new(pool);
let _ = disp.pool();
Source

pub fn with_mbuf_pool(self, pool: MbufPool) -> Self

Override the dispatcher’s mbuf pool. Useful when the embedding wants every synthetic error payload to come from the same recycled buffers as the rest of the engine.

§Examples
let pool = Arc::new(ServerPool::new(cfg, vec![local]));
let _disp = ClusterDispatcher::new(pool).with_mbuf_pool(MbufPool::default());
Source

pub fn mbuf_pool(&self) -> &MbufPool

Borrow the dispatcher’s mbuf pool. Exposed so embedders can reuse the same pool when building synthetic responses outside the dispatcher’s own code paths.

Source

pub fn with_backend(self, backend: Sender<OutboundRequest>) -> Self

Attach a backend request channel. Calls to Self::dispatch that produce a DispatchPlan::LocalDatastore plan will forward the request bytes onto this channel for the local datastore driver to write to the backend.

The channel sender must be the request side of a crate::net::ServerConn task; multiple senders cloned from the same channel are fine.

Source

pub fn with_peer_backend( self, peer_idx: u32, sender: Sender<OutboundRequest>, ) -> Self

Attach an outbound channel for a single peer (by Peer::idx). The supplied sender feeds a crate::net::DnodeServerConn task that writes dnode-framed requests to the peer’s dyn_listen and routes the response back through the per-request responder channel.

Wiring is additive: call this once per non-local peer. Calling it again with the same peer_idx replaces the previous sender (used by reconnect supervisors that rebuild channels on restart).

Source

pub fn has_backend(&self) -> bool

Whether a backend channel is wired.

Source

pub fn peer_backend_count(&self) -> usize

Number of peer-backend channels wired.

Source

pub fn pool(&self) -> &Arc<ServerPool>

Borrow the underlying pool.

Source

pub fn with_hint_store(self, store: Arc<HintStore>) -> Self

Attach a crate::cluster::hints::HintStore.

When set AND the pool’s enable_hinted_handoff flag is true, write requests targeted at peers in crate::cluster::peer::PeerState::Down (or at peers whose outbound channel is closed / full) are stored as hints and counted toward the consistency threshold. The background drainer task in dynomited is responsible for shipping the hints back to the peer once it returns to crate::cluster::peer::PeerState::Normal. Without this builder call (or with enable_hinted_handoff: false) the dispatcher behaviour is unchanged: a Down or unreachable target is silently skipped.

§Examples
let cfg = PoolConfig { enable_hinted_handoff: true, ..PoolConfig::default() };
let local = Peer::new(
    0, PeerEndpoint::tcp("h".into(), 1), "r".into(), "d".into(),
    vec![DynToken::from_u32(0)], true, true, false,
);
let pool = Arc::new(ServerPool::new(cfg, vec![local]));
let store = Arc::new(HintStore::new(64 * 1024 * 1024));
let _disp = ClusterDispatcher::new(pool).with_hint_store(store);
Source

pub fn hint_store(&self) -> Option<&Arc<HintStore>>

Borrow the wired hint store, if any.

Source

pub fn with_failure_metrics(self, metrics: Arc<FailureMetrics>) -> Self

Attach a crate::stats::FailureMetrics handle.

When wired, each error-producing branch in the dispatcher (no-targets, peer-channel-full, peer-channel-closed, backend-channel-full, backend-channel-closed, response-timeout) increments the matching counter so an operator can pull the per-cause histogram off the /stats and /metrics endpoints. The default behaviour is unchanged when no metrics handle is supplied.

§Examples
let cfg = PoolConfig::default();
let local = Peer::new(
    0, PeerEndpoint::tcp("h".into(), 1), "r".into(), "d".into(),
    vec![DynToken::from_u32(0)], true, true, false,
);
let pool = Arc::new(ServerPool::new(cfg, vec![local]));
let metrics = Arc::new(FailureMetrics::new());
let _disp = ClusterDispatcher::new(pool).with_failure_metrics(metrics);
Source

pub fn failure_metrics(&self) -> Option<&Arc<FailureMetrics>>

Borrow the wired failure-metrics handle, if any.

Source

pub fn with_command_extension(self, ext: Arc<dyn CommandExtension>) -> Self

Attach a crate::embed::CommandExtension.

When wired, parsed FT.* requests and HSET requests are offered to the extension before the routing planner runs. The extension may produce a synthesised RESP reply (returned to the client as crate::net::DispatchOutcome::Inline), surface a structured -ERR ... reply (crate::net::DispatchOutcome::Error), or fall through. Without this builder call the dispatcher’s behaviour is unchanged: FT.* keywords are forwarded to the local datastore (which typically rejects them with -ERR unknown command) and HSETs proceed unmodified.

The standard RediSearch implementation lives in the dynomite-search crate; the trait itself is part of the engine so embedders can plug their own.

§Examples
#[derive(Debug)]
struct NoOp;
impl CommandExtension for NoOp {
    fn handles_msg_type(&self, _: MsgType) -> bool { false }
    fn try_dispatch(&self, _: &[&[u8]]) -> Option<Vec<u8>> { None }
}
let cfg = PoolConfig::default();
let local = Peer::new(
    0, PeerEndpoint::tcp("h".into(), 1), "r".into(), "d".into(),
    vec![DynToken::from_u32(0)], true, true, false,
);
let pool = Arc::new(ServerPool::new(cfg, vec![local]));
let _disp = ClusterDispatcher::new(pool).with_command_extension(Arc::new(NoOp));
Source

pub fn command_extension(&self) -> Option<&Arc<dyn CommandExtension>>

Borrow the wired command extension, if any.

Source

pub fn hinted_handoff_active(&self) -> bool

True when both the hint store is wired AND the pool has enable_hinted_handoff: true. Hot-path predicate.

Source

pub fn plan(&self, req: &Msg, key: &[u8]) -> DispatchPlan

Compute the routing plan for req with the supplied key.

key is the primary key of the request (the first key returned by Msg::keys for parsed redis / memcache commands, or an empty slice for argument-less commands).

The function never panics; it consults the live peer table behind the pool’s RwLock and returns DispatchPlan::NoTargets when the topology cannot satisfy the request.

§Examples

See the module-level example.

Trait Implementations§

Source§

impl Clone for ClusterDispatcher

Source§

fn clone(&self) -> ClusterDispatcher

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ClusterDispatcher

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Dispatcher for ClusterDispatcher

Source§

fn dispatch(&self, req: Msg, responder: ServerSink) -> DispatchOutcome

Hand a parsed request to the dispatcher. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,