pub struct StorageReplicationManager {
pub targets: HashMap<ReplicaId, ReplicaTarget>,
pub pending_ops: VecDeque<ReplicationOp>,
pub replication_log: Vec<ReplicationLogEntry>,
pub config: SrmReplicationConfig,
/* private fields */
}Expand description
Production-grade storage replication manager.
Maintains:
- A registry of up to
max_replicasReplicaTargetnodes. - A bounded
VecDequeof pendingReplicationOps. - A rolling
Vecof the lastMAX_LOG_ENTRIESReplicationLogEntryrecords. - Accumulated
SrmReplicationStats.
Call process_batch periodically to drain the queue and
simulate replication outcomes using the inline xorshift64 PRNG.
Fields§
§targets: HashMap<ReplicaId, ReplicaTarget>Registered replication targets indexed by their ReplicaId.
pending_ops: VecDeque<ReplicationOp>Bounded queue of pending replication operations.
replication_log: Vec<ReplicationLogEntry>Rolling log of recent replication attempts.
config: SrmReplicationConfigManager configuration.
Implementations§
Source§impl StorageReplicationManager
impl StorageReplicationManager
Sourcepub fn new(config: SrmReplicationConfig) -> Self
pub fn new(config: SrmReplicationConfig) -> Self
Create a new manager with the given configuration.
The PRNG is seeded deterministically from the config values so that unit tests are reproducible without an external random source.
Sourcepub fn with_defaults() -> Self
pub fn with_defaults() -> Self
Create a manager with default configuration.
Sourcepub fn add_replica(&mut self, target: ReplicaTarget) -> Result<(), SrmError>
pub fn add_replica(&mut self, target: ReplicaTarget) -> Result<(), SrmError>
Register a new replication target.
§Errors
SrmError::RegistryFullifmax_replicasis already reached.SrmError::DuplicateReplicaif the id is already registered.
Sourcepub fn remove_replica(
&mut self,
id: ReplicaId,
) -> Result<ReplicaTarget, SrmError>
pub fn remove_replica( &mut self, id: ReplicaId, ) -> Result<ReplicaTarget, SrmError>
Remove a replication target by id.
§Errors
SrmError::ReplicaNotFoundif no target withidis registered.
Sourcepub fn mark_unhealthy(&mut self, id: ReplicaId) -> Result<(), SrmError>
pub fn mark_unhealthy(&mut self, id: ReplicaId) -> Result<(), SrmError>
Mark a replica as unhealthy. Does nothing (ok) if the replica is already unhealthy.
§Errors
SrmError::ReplicaNotFoundif no target withidis registered.
Sourcepub fn mark_healthy(&mut self, id: ReplicaId) -> Result<(), SrmError>
pub fn mark_healthy(&mut self, id: ReplicaId) -> Result<(), SrmError>
Mark a previously unhealthy replica as healthy again.
§Errors
SrmError::ReplicaNotFoundif no target withidis registered.
Sourcepub fn set_priority(
&mut self,
id: ReplicaId,
priority: u32,
) -> Result<(), SrmError>
pub fn set_priority( &mut self, id: ReplicaId, priority: u32, ) -> Result<(), SrmError>
Update the priority of a registered replica.
§Errors
SrmError::ReplicaNotFoundif no target withidis registered.
Sourcepub fn enqueue_put(&mut self, cid: [u8; 32], data_len: usize) -> bool
pub fn enqueue_put(&mut self, cid: [u8; 32], data_len: usize) -> bool
Enqueue a Put replication operation.
Returns false (and increments queue_overflow_count) if the queue is full.
Sourcepub fn enqueue_delete(&mut self, cid: [u8; 32]) -> bool
pub fn enqueue_delete(&mut self, cid: [u8; 32]) -> bool
Enqueue a Delete replication operation.
Returns false if the queue is full.
Sourcepub fn enqueue_sync(&mut self, since_ts: u64) -> bool
pub fn enqueue_sync(&mut self, since_ts: u64) -> bool
Enqueue a full incremental Sync operation.
Returns false if the queue is full.
Sourcepub fn process_batch(&mut self) -> SrmBatchResult
pub fn process_batch(&mut self) -> SrmBatchResult
Drain up to batch_size pending operations and simulate replication.
For each operation the manager iterates over all healthy replicas and
uses xorshift64 (seeded from the CID + replica-id) to decide success or
failure (success probability ≈ 7/8 for Put/Delete, 3/4 for Sync).
Results are appended to the rolling log (capped at MAX_LOG_ENTRIES).
Statistics are updated atomically per batch.
Sourcepub fn check_quorum(&self, required: usize) -> bool
pub fn check_quorum(&self, required: usize) -> bool
Return true if at least required replicas are currently healthy.
Sourcepub fn recovery_plan(&self) -> Vec<ReplicaId> ⓘ
pub fn recovery_plan(&self) -> Vec<ReplicaId> ⓘ
Return the ids of all unhealthy replicas that need re-synchronisation.
Sourcepub fn replication_stats(&self) -> SrmReplicationStats
pub fn replication_stats(&self) -> SrmReplicationStats
Return a snapshot of current statistics.
Sourcepub fn healthy_replica_count(&self) -> usize
pub fn healthy_replica_count(&self) -> usize
Return the number of healthy replicas.
Sourcepub fn replica_count(&self) -> usize
pub fn replica_count(&self) -> usize
Return the number of registered replicas.
Sourcepub fn replica_health_counts(&self) -> (usize, usize)
pub fn replica_health_counts(&self) -> (usize, usize)
Return (healthy, unhealthy) counts.
Sourcepub fn get_replica(&self, id: &ReplicaId) -> Option<&ReplicaTarget>
pub fn get_replica(&self, id: &ReplicaId) -> Option<&ReplicaTarget>
Return a reference to a replica by id.
Sourcepub fn get_replica_mut(&mut self, id: &ReplicaId) -> Option<&mut ReplicaTarget>
pub fn get_replica_mut(&mut self, id: &ReplicaId) -> Option<&mut ReplicaTarget>
Return a mutable reference to a replica by id.
Sourcepub fn pending_count(&self) -> usize
pub fn pending_count(&self) -> usize
Return the number of pending operations.
Sourcepub fn log_entries_for_kind(&self, kind: &str) -> Vec<&ReplicationLogEntry>
pub fn log_entries_for_kind(&self, kind: &str) -> Vec<&ReplicationLogEntry>
Return entries from the replication log whose op_kind matches kind.
Sourcepub fn failed_log_entries(&self) -> Vec<&ReplicationLogEntry>
pub fn failed_log_entries(&self) -> Vec<&ReplicationLogEntry>
Return only failed log entries.
Sourcepub fn drain_pending(&mut self) -> usize
pub fn drain_pending(&mut self) -> usize
Drain the pending queue and discard all operations (useful for shutdown).
Sourcepub fn reset_stats(&mut self)
pub fn reset_stats(&mut self)
Reset statistics (but not configuration or targets).
Sourcepub fn total_bytes_across_targets(&self) -> u64
pub fn total_bytes_across_targets(&self) -> u64
Return total bytes replicated across all registered targets.
Sourcepub fn most_active_replica(&self) -> Option<&ReplicaTarget>
pub fn most_active_replica(&self) -> Option<&ReplicaTarget>
Return the replica with the most bytes replicated, if any.
Sourcepub fn least_active_replica(&self) -> Option<&ReplicaTarget>
pub fn least_active_replica(&self) -> Option<&ReplicaTarget>
Return the replica with the fewest bytes replicated (least-loaded), if any.
Sourcepub fn has_minimum_quorum(&self) -> bool
pub fn has_minimum_quorum(&self) -> bool
True if a quorum of at least min_replicas healthy targets is available.
Sourcepub fn replicas_by_priority(&self) -> Vec<ReplicaId> ⓘ
pub fn replicas_by_priority(&self) -> Vec<ReplicaId> ⓘ
Return the list of replica ids sorted by priority (ascending = highest priority first).
Sourcepub fn healthy_replica_ids(&self) -> Vec<ReplicaId> ⓘ
pub fn healthy_replica_ids(&self) -> Vec<ReplicaId> ⓘ
Return all healthy replica ids.
Sourcepub fn unhealthy_replica_ids(&self) -> Vec<ReplicaId> ⓘ
pub fn unhealthy_replica_ids(&self) -> Vec<ReplicaId> ⓘ
Return all unhealthy replica ids.
Sourcepub fn last_log_entry(&self) -> Option<&ReplicationLogEntry>
pub fn last_log_entry(&self) -> Option<&ReplicationLogEntry>
Return the most-recent log entry, if any.
Sourcepub fn log_success_count(&self) -> usize
pub fn log_success_count(&self) -> usize
Count log entries that succeeded.
Sourcepub fn log_failure_count(&self) -> usize
pub fn log_failure_count(&self) -> usize
Count log entries that failed.
Sourcepub fn log_success_rate(&self) -> f64
pub fn log_success_rate(&self) -> f64
Compute the success rate across all log entries (0.0 if log is empty).
Sourcepub fn log_total_bytes(&self) -> usize
pub fn log_total_bytes(&self) -> usize
Sum of bytes in all log entries.
Sourcepub fn log_entries_for_replica(
&self,
id: &ReplicaId,
) -> Vec<&ReplicationLogEntry>
pub fn log_entries_for_replica( &self, id: &ReplicaId, ) -> Vec<&ReplicationLogEntry>
Return all log entries for a specific replica.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for StorageReplicationManager
impl RefUnwindSafe for StorageReplicationManager
impl Send for StorageReplicationManager
impl Sync for StorageReplicationManager
impl Unpin for StorageReplicationManager
impl UnsafeUnpin for StorageReplicationManager
impl UnwindSafe for StorageReplicationManager
Blanket Implementations§
impl<T> Allocation 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> 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 more