Skip to main content

PeerLogScanner

Struct PeerLogScanner 

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

A LogScanner backed by an in-memory queue of (vlsn, type, payload) entries.

Entries are pushed by the ReplicaReceiver as they arrive from the master (or from another peer). A FeederRunner driving a PeerScannerAdapter consumes entries from this queue and streams them to a downstream replica (the in-memory, env-less convenience source).

§Bounded memory (F10)

The queue has two configurable bounds:

On push, if either bound is exceeded the oldest entries are evicted from the front of the queue until both bounds are satisfied. The evicted entries are no longer available for peer streaming through this scanner; downstream peers that fall behind the eviction window must catch up via the on-disk EnvironmentLogScanner or via network restore. This matches HA semantics where peer-to-peer log distribution is best-effort and the on-disk log is the durable source.

Closes finding F10 of the 2026 review.

Thread safety: the queue is protected by a Mutex so that the receiver thread (writer) and the feeder thread (reader) can operate concurrently.

Implementations§

Source§

impl PeerLogScanner

Source

pub fn new() -> Self

Create an empty scanner with the default F10 bounds.

Source

pub fn with_capacity(max_entries: usize, max_bytes: usize) -> Self

Create an empty scanner with explicit bounds.

max_entries and max_bytes are both honoured; whichever is breached first triggers oldest-evicting on subsequent push calls. Passing usize::MAX disables the corresponding bound (not recommended in production).

Source

pub fn push(&self, vlsn: u64, entry_type: u8, payload: Vec<u8>)

Push a log entry into the scanner’s queue.

Called by the ReplicaReceiver each time an entry is applied. Entries are expected to be pushed in VLSN order, but this method is not enforcing: every entry is appended to the queue unconditionally and the cached (first_vlsn, last_vlsn) range is widened to cover the new VLSN. Out-of-order or duplicate entries are filtered later by LogScanner::next_entry, which skips entries with vlsn < from_vlsn.

F10 bound: after the new entry is appended, if the queue exceeds either max_entries or max_bytes, the oldest entries are evicted from the front until both bounds are satisfied. The retained first_vlsn is updated to the new front-of-queue VLSN so downstream peers that ask for an evicted VLSN range observe log_range().first > from_vlsn and know they must catch up via the durable log.

Source

pub fn evicted_count(&self) -> u64

Cumulative number of entries dropped by the F10 bound since scanner construction. Useful for monitoring whether downstream peers are keeping up.

Source

pub fn current_bytes(&self) -> usize

Current cumulative payload size in bytes (live snapshot).

Source

pub fn log_range(&self) -> Option<(u64, u64)>

Return the VLSN range currently held in this scanner.

Returns None if the scanner is empty (no entries pushed yet).

Source

pub fn len(&self) -> usize

Return the number of entries currently queued.

Source

pub fn is_empty(&self) -> bool

Returns true if no entries are queued.

Trait Implementations§

Source§

impl Default for PeerLogScanner

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl LogScanner for PeerLogScanner

Source§

fn next_entry(&mut self, from_vlsn: u64) -> Option<(u64, u8, Vec<u8>)>

Return the next available entry with VLSN >= from_vlsn, or None if no new entry is available at this moment.

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 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