v0.3.14-pre.003
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-worker-raw-transaction-ingest-lib/src/continuity.rs
|
||||
// version: 3
|
||||
// version: 4
|
||||
|
||||
/// Maximum number of simultaneously retained non-repaired run-local gaps.
|
||||
const MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS: usize = 64;
|
||||
@@ -150,6 +150,85 @@ impl RawTransactionIngestGapRange {
|
||||
}
|
||||
}
|
||||
|
||||
/// Private run-local anchor for one WebSocket continuity incident.
|
||||
///
|
||||
/// The anchor never derives slots from wall-clock time. Its inclusive start is the latest slot actually observed by that source before Transport reported a
|
||||
/// reconnect or notification overflow; the end remains absent until the first post-incident source slot is observed.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(crate) struct RawTransactionIngestWebSocketIncidentAnchor {
|
||||
end_slot: std::option::Option<u64>,
|
||||
overflow_total: u64,
|
||||
reconnect_total: u64,
|
||||
saw_overflow: bool,
|
||||
saw_reconnect: bool,
|
||||
start_slot: u64,
|
||||
}
|
||||
|
||||
impl crate::RawTransactionIngestWebSocketIncidentAnchor {
|
||||
/// Creates one open incident anchor from monotone Transport counters and one actually observed source slot.
|
||||
pub(crate) fn new(start_slot: u64, reconnect_total: u64, overflow_total: u64, saw_reconnect: bool, saw_overflow: bool) -> ksp_core_lib::Result<Self> {
|
||||
if !saw_reconnect && !saw_overflow {
|
||||
return std::result::Result::Err(crate::runtime_error("continuity.websocket_incident_reason_missing"));
|
||||
}
|
||||
return std::result::Result::Ok(Self {
|
||||
end_slot: std::option::Option::None,
|
||||
overflow_total,
|
||||
reconnect_total,
|
||||
saw_overflow,
|
||||
saw_reconnect,
|
||||
start_slot,
|
||||
});
|
||||
}
|
||||
|
||||
/// Extends one still-open incident with newer monotone Transport counters without changing its earliest start slot.
|
||||
pub(crate) fn extend(&mut self, reconnect_total: u64, overflow_total: u64, saw_reconnect: bool, saw_overflow: bool) -> ksp_core_lib::Result<()> {
|
||||
if self.end_slot.is_some() {
|
||||
return std::result::Result::Err(crate::runtime_error("continuity.websocket_incident_already_closed"));
|
||||
}
|
||||
if reconnect_total < self.reconnect_total || overflow_total < self.overflow_total {
|
||||
return std::result::Result::Err(crate::runtime_error("continuity.websocket_incident_counter_regression"));
|
||||
}
|
||||
self.reconnect_total = reconnect_total;
|
||||
self.overflow_total = overflow_total;
|
||||
self.saw_reconnect = self.saw_reconnect || saw_reconnect;
|
||||
self.saw_overflow = self.saw_overflow || saw_overflow;
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
|
||||
/// Closes the inclusive incident range at the first post-incident source slot.
|
||||
pub(crate) fn close_at(&mut self, end_slot: u64) -> ksp_core_lib::Result<()> {
|
||||
let range = match RawTransactionIngestGapRange::new(self.start_slot, end_slot) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
self.end_slot = std::option::Option::Some(range.end_slot());
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
|
||||
/// Returns the first source slot that safely anchors the incident, inclusively.
|
||||
#[cfg(test)]
|
||||
pub(crate) const fn start_slot(self) -> u64 {
|
||||
return self.start_slot;
|
||||
}
|
||||
|
||||
/// Returns the first post-incident source slot when the incident has become range-bounded.
|
||||
pub(crate) const fn end_slot(self) -> std::option::Option<u64> {
|
||||
return self.end_slot;
|
||||
}
|
||||
|
||||
/// Returns whether at least one physical WebSocket reconnect contributed to this incident.
|
||||
#[cfg(test)]
|
||||
pub(crate) const fn saw_reconnect(self) -> bool {
|
||||
return self.saw_reconnect;
|
||||
}
|
||||
|
||||
/// Returns whether at least one Transport notification overflow contributed to this incident.
|
||||
#[cfg(test)]
|
||||
pub(crate) const fn saw_overflow(self) -> bool {
|
||||
return self.saw_overflow;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
struct RawTransactionIngestGapId(u64);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user