pub struct InstanceLeader { /* private fields */ }Expand description
Primary leader implementation for the distributed KVBM system.
InstanceLeader coordinates block onboarding across local and remote
instances. It owns a G2 (host memory) BlockManager and an optional G3
(disk) BlockManager, a set of workers for executing physical transfers,
and a parallel worker abstraction for multi-rank RDMA operations.
Key responsibilities:
- Block matching: finding which requested sequence hashes are already
cached locally (via
BlockAccessorpolicies). - Session management: creating, attaching, and driving onboard sessions between endpoint (source) and controller (destination) roles.
- Remote connectivity: exchanging serialized layout metadata with peer instances so workers can perform RDMA transfers.
- Velo RPC: registering handlers via
VeloLeaderServiceso remote leaders can initiate sessions and exchange metadata.
Implementations§
Source§impl InstanceLeader
impl InstanceLeader
Sourcepub fn g2_manager(&self) -> &Arc<BlockManager<G2>> ⓘ
pub fn g2_manager(&self) -> &Arc<BlockManager<G2>> ⓘ
Get a reference to the G2 BlockManager.
Sourcepub fn g3_manager(&self) -> Option<&Arc<BlockManager<G3>>>
pub fn g3_manager(&self) -> Option<&Arc<BlockManager<G3>>>
Get a reference to the optional G3 BlockManager.
Sourcepub fn registry(&self) -> &BlockRegistry
pub fn registry(&self) -> &BlockRegistry
Get the block registry.
Sourcepub fn messenger(&self) -> &Arc<Messenger> ⓘ
pub fn messenger(&self) -> &Arc<Messenger> ⓘ
Get a reference to the Nova instance.
This provides access to the Nova distributed system for features like event coordination and cross-instance communication.
Sourcepub fn runtime(&self) -> Handle
pub fn runtime(&self) -> Handle
Get the tokio runtime handle from Nova.
This handle should be used for spawning background tasks that need to run on the KVBM runtime’s executor (e.g., offload engine pipelines).
Sourcepub fn has_parallel_worker(&self) -> bool
pub fn has_parallel_worker(&self) -> bool
Check if a parallel_worker is configured.
The parallel_worker is required for local transfer operations (e.g., offloading blocks between tiers).
Sourcepub fn parallel_worker(&self) -> Option<Arc<dyn ParallelWorkers>>
pub fn parallel_worker(&self) -> Option<Arc<dyn ParallelWorkers>>
Get the parallel worker for distributed operations.
The parallel worker fans out operations to all workers and aggregates results.
It implements ObjectBlockOps for coordinated object storage uploads.
Sourcepub fn object_client(&self) -> Option<Arc<dyn ObjectBlockOps>>
pub fn object_client(&self) -> Option<Arc<dyn ObjectBlockOps>>
Get the object storage client for G4 operations.
Returns Some if object storage is configured, None otherwise.
The client is used by InitiatorSession for G4 parallel search.
Sourcepub fn add_remote_leader(&self, instance_id: InstanceId)
pub fn add_remote_leader(&self, instance_id: InstanceId)
Add a remote leader to the search list.
Remote leaders are queried during find_matches_with_options when
search_remote == true. This method allows adding remote leaders
after construction (e.g., when instance IDs are only known after
cluster setup).
Sourcepub fn set_remote_leaders(&self, instance_ids: Vec<InstanceId>)
pub fn set_remote_leaders(&self, instance_ids: Vec<InstanceId>)
Set all remote leaders at once.
Sourcepub fn remote_leaders(&self) -> Vec<InstanceId>
pub fn remote_leaders(&self) -> Vec<InstanceId>
Get the list of remote leader instance IDs.
Sourcepub fn scan_blocks(
&self,
sequence_hashes: &[SequenceHash],
touch: bool,
) -> ScanBlocksResult
pub fn scan_blocks( &self, sequence_hashes: &[SequenceHash], touch: bool, ) -> ScanBlocksResult
Scan for all blocks matching any of the given sequence hashes.
Unlike find_matches, this:
- Does NOT stop on first miss
- Returns blocks from both G2 and G3 tiers separately
- Acquires blocks from pools (caller owns until dropped via RAII)
- Returns
sorted_matchesordered bySequenceHash::position()
§Arguments
sequence_hashes- Hashes to scan fortouch- Whether to update frequency tracking (for MultiLRU eviction policy)
§Algorithm
- Scan G2 manager for candidates
- Scan G3 manager for remaining candidates
- Build sorted_matches from both, sorted by position (lowest to highest)
Sourcepub fn scan_with_policy<F, T>(
&self,
hashes: &[SequenceHash],
touch: bool,
policy: F,
) -> Vec<T>
pub fn scan_with_policy<F, T>( &self, hashes: &[SequenceHash], touch: bool, policy: F, ) -> Vec<T>
Scan blocks using a custom policy that controls iteration and yields results.
This provides maximum flexibility for implementing custom scanning strategies.
The policy receives access to a BlockAccessor for acquiring blocks and a
PolicyContext for yielding results incrementally.
§Arguments
hashes- Sequence hashes to scantouch- Whether to update frequency tracking on block accesspolicy- Function that implements the scanning strategy
§Design
The accessor does NOT hold locks between calls. Each .find() call is
independent. This enables:
- Custom iteration patterns (sorted, BTree scan, binary search, etc.)
- Yielding results incrementally (e.g., contiguous subsequences)
- Future parallel execution (accessor is Send + Sync)
§Example: Simple linear scan
let blocks = leader.scan_with_policy(&hashes, true, |hashes, ctx| {
for hash in hashes {
if let Some(block) = ctx.accessor().find(*hash) {
ctx.yield_item(block);
}
}
});§Example: Find contiguous subsequences
let runs: Vec<Vec<TieredBlock>> = leader.scan_with_policy(&hashes, true, |hashes, ctx| {
let mut run = Vec::new();
let mut last_pos: Option<u64> = None;
for hash in hashes.iter().sorted_by_key(|h| h.position()) {
if let Some(block) = ctx.accessor().find(*hash) {
let pos = block.position();
if last_pos.map_or(true, |p| pos == p + 1) {
run.push(block);
} else {
if !run.is_empty() { ctx.yield_item(std::mem::take(&mut run)); }
run.push(block);
}
last_pos = Some(pos);
} else if !run.is_empty() {
ctx.yield_item(std::mem::take(&mut run));
last_pos = None;
}
}
if !run.is_empty() { ctx.yield_item(run); }
});pub fn builder() -> InstanceLeaderBuilder
Sourcepub fn register_handlers(&self) -> Result<()>
pub fn register_handlers(&self) -> Result<()>
Register Nova handlers for leader-to-leader communication.
This must be called after construction to enable distributed onboarding.
Sourcepub fn release_session(&self, session_id: SessionId)
pub fn release_session(&self, session_id: SessionId)
Release a completed session, dropping any held blocks.
This is optional - sessions will naturally be cleaned up when the InstanceLeader is dropped. Call this explicitly if you need to release blocks earlier.
Sourcepub fn create_controllable_session(
&self,
sequence_hashes: &[SequenceHash],
) -> Result<ControllableSessionResult>
pub fn create_controllable_session( &self, sequence_hashes: &[SequenceHash], ) -> Result<ControllableSessionResult>
Create a controllable session for local blocks.
This is the “Decode side” of the inverted control pattern:
- Search local G2 and G3 for matches
- Create a ControllableSession that holds the blocks
- Return session_id to be sent to Prefill out-of-band
By default, G3→G2 staging starts immediately (auto_stage=true).
Sourcepub fn create_controllable_session_with_options(
&self,
sequence_hashes: &[SequenceHash],
options: ControllableSessionOptions,
) -> Result<ControllableSessionResult>
pub fn create_controllable_session_with_options( &self, sequence_hashes: &[SequenceHash], options: ControllableSessionOptions, ) -> Result<ControllableSessionResult>
Create a controllable session with custom options.
Use this when you need to control auto-staging behavior.
Sourcepub async fn attach_session(
&self,
remote_instance: InstanceId,
session_id: SessionId,
) -> Result<SessionHandle>
pub async fn attach_session( &self, remote_instance: InstanceId, session_id: SessionId, ) -> Result<SessionHandle>
Attach to a remote session.
Returns a SessionHandle that uses SessionMessage for communication.
§Arguments
remote_instance- The instance hosting the sessionsession_id- The session to attach to
§Example
let handle = leader.attach_session(remote_id, session_id).await?;
let state = handle.wait_for_ready().await?;
handle.trigger_staging().await?;Sourcepub fn create_endpoint_session(
&self,
sequence_hashes: &[SequenceHash],
) -> Result<(SessionId, ServerSessionHandle)>
pub fn create_endpoint_session( &self, sequence_hashes: &[SequenceHash], ) -> Result<(SessionId, ServerSessionHandle)>
Create an endpoint session that a remote peer can attach to.
This searches local G2/G3 for blocks matching the given sequence hashes and creates a session that exposes them for remote RDMA pull.
Returns (session_id, handle) where:
session_id- Send to remote peer for attachmenthandle- Use to control the session (send layer notifications, close)
§Example
// Create session for sequence hashes
let (session_id, handle) = leader.create_endpoint_session(&hashes)?;
// Send session_id to remote peer out-of-band
// Remote attaches via: remote_leader.attach_session(local_id, session_id)
// For layerwise transfer, notify when layers are ready
handle.notify_layers_ready(0..1).await?;Sourcepub fn create_endpoint_session_for_blocks(
&self,
blocks: BlockHolder<G2>,
sequence_hashes: &[SequenceHash],
layout_handles: &[LayoutHandle],
) -> Result<(SessionId, ServerSessionHandle)>
pub fn create_endpoint_session_for_blocks( &self, blocks: BlockHolder<G2>, sequence_hashes: &[SequenceHash], layout_handles: &[LayoutHandle], ) -> Result<(SessionId, ServerSessionHandle)>
Create an endpoint session for specific pre-allocated blocks.
Unlike create_endpoint_session, this doesn’t search - it uses the
provided blocks directly. Useful when the caller already has blocks
to expose (e.g., after prefill computation).
§Arguments
blocks- Blocks to expose for RDMA pullsequence_hashes- Sequence hashes for the blocks (must match block count)layout_handles- Layout handles for the blocks (must match block count)
§Example
// After prefill computation, expose blocks for Decode to pull
let (session_id, handle) = leader.create_endpoint_session_for_blocks(
prefill_blocks,
&hashes,
&layout_handles,
)?;Sourcepub fn has_remote_metadata(&self, instance: InstanceId) -> bool
pub fn has_remote_metadata(&self, instance: InstanceId) -> bool
Check if metadata for a remote instance has been loaded.
Returns true if import_remote_metadata has been successfully called
for the given instance.
Sourcepub fn worker_count(&self) -> usize
pub fn worker_count(&self) -> usize
Get the number of workers attached to this leader.
Sourcepub async fn export_worker_metadata(&self) -> Result<Vec<SerializedLayout>>
pub async fn export_worker_metadata(&self) -> Result<Vec<SerializedLayout>>
Export metadata from all workers.
Returns a Vec<SerializedLayout> where each element corresponds to a worker
in rank order. This metadata can be sent to remote instances to enable
RDMA transfers.
§Returns
Vector of serialized layouts, one per worker
Sourcepub async fn import_remote_metadata(
&self,
remote_instance: InstanceId,
metadata: Vec<SerializedLayout>,
) -> Result<()>
pub async fn import_remote_metadata( &self, remote_instance: InstanceId, metadata: Vec<SerializedLayout>, ) -> Result<()>
Import metadata from a remote instance’s workers.
This imports layout metadata from a remote instance, enabling RDMA transfers to pull data from that instance. Metadata is imported rank-by-rank:
- local worker 0 imports remote worker 0’s metadata
- local worker 1 imports remote worker 1’s metadata
- etc.
§Arguments
remote_instance- The instance ID of the remote leadermetadata- Vector of SerializedLayout from remote workers (one per worker)
§Errors
Returns an error if:
- No parallel worker configured
- Metadata was already imported for this instance
- Worker count mismatch between local and remote
- Individual worker metadata import fails
Trait Implementations§
Source§impl Clone for InstanceLeader
impl Clone for InstanceLeader
Source§fn clone(&self) -> InstanceLeader
fn clone(&self) -> InstanceLeader
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Leader for InstanceLeader
impl Leader for InstanceLeader
Source§fn find_matches_with_options(
&self,
sequence_hashes: &[SequenceHash],
options: FindMatchesOptions,
) -> Result<FindMatchesResult>
fn find_matches_with_options( &self, sequence_hashes: &[SequenceHash], options: FindMatchesOptions, ) -> Result<FindMatchesResult>
Source§fn find_matches(
&self,
sequence_hashes: &[SequenceHash],
) -> Result<FindMatchesResult>
fn find_matches( &self, sequence_hashes: &[SequenceHash], ) -> Result<FindMatchesResult>
Auto Trait Implementations§
impl !RefUnwindSafe for InstanceLeader
impl !UnwindSafe for InstanceLeader
impl Freeze for InstanceLeader
impl Send for InstanceLeader
impl Sync for InstanceLeader
impl Unpin for InstanceLeader
impl UnsafeUnpin for InstanceLeader
Blanket Implementations§
impl<T> BlockMetadata for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);