v0.3.14-pre.009
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-worker-raw-transaction-ingest-lib/src/snapshot.rs
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
/// Runtime-neutral boxed future resolving to one newer concrete RAW transaction ingest Worker snapshot.
|
||||
pub type RawTransactionIngestSnapshotFuture<'a> =
|
||||
@@ -23,6 +23,11 @@ pub enum RawTransactionIngestSourceState {
|
||||
/// Private latest-value source-processing projection emitted by the productive source task.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(crate) struct RawTransactionIngestProcessingFrontierProjection {
|
||||
continuity_frontier_slot: std::option::Option<u64>,
|
||||
continuity_has_open_gaps: bool,
|
||||
continuity_policy_observed: bool,
|
||||
failed_source_losses_reconciled: bool,
|
||||
future_target_coverage: bool,
|
||||
hydration_pending: usize,
|
||||
processing_frontier_slot: std::option::Option<u64>,
|
||||
oldest_pending_slot: std::option::Option<u64>,
|
||||
@@ -40,6 +45,11 @@ impl crate::RawTransactionIngestProcessingFrontierProjection {
|
||||
/// Returns the empty run-local processing projection used before the source observes work.
|
||||
pub(crate) const fn empty() -> Self {
|
||||
return Self {
|
||||
continuity_frontier_slot: std::option::Option::None,
|
||||
continuity_has_open_gaps: false,
|
||||
continuity_policy_observed: false,
|
||||
failed_source_losses_reconciled: false,
|
||||
future_target_coverage: false,
|
||||
hydration_pending: 0,
|
||||
processing_frontier_slot: std::option::Option::None,
|
||||
oldest_pending_slot: std::option::Option::None,
|
||||
@@ -61,6 +71,11 @@ impl crate::RawTransactionIngestProcessingFrontierProjection {
|
||||
oldest_pending_slot: std::option::Option<u64>,
|
||||
) -> Self {
|
||||
return Self {
|
||||
continuity_frontier_slot: std::option::Option::None,
|
||||
continuity_has_open_gaps: false,
|
||||
continuity_policy_observed: false,
|
||||
failed_source_losses_reconciled: false,
|
||||
future_target_coverage: false,
|
||||
hydration_pending,
|
||||
processing_frontier_slot,
|
||||
oldest_pending_slot,
|
||||
@@ -114,6 +129,51 @@ impl crate::RawTransactionIngestProcessingFrontierProjection {
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Returns a copy carrying source-neutral run-local continuity evidence used only for Worker health classification.
|
||||
pub(crate) const fn with_continuity_health(
|
||||
mut self,
|
||||
continuity_frontier_slot: std::option::Option<u64>,
|
||||
continuity_has_open_gaps: bool,
|
||||
future_target_coverage: bool,
|
||||
) -> Self {
|
||||
self.continuity_frontier_slot = continuity_frontier_slot;
|
||||
self.continuity_has_open_gaps = continuity_has_open_gaps;
|
||||
self.continuity_policy_observed = true;
|
||||
self.future_target_coverage = future_target_coverage;
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Returns whether a run-local continuity policy projection has been observed.
|
||||
pub(crate) const fn continuity_policy_observed(&self) -> bool {
|
||||
return self.continuity_policy_observed;
|
||||
}
|
||||
|
||||
/// Returns the gap-aware continuity frontier carried by this private projection.
|
||||
pub(crate) const fn continuity_frontier_slot(&self) -> std::option::Option<u64> {
|
||||
return self.continuity_frontier_slot;
|
||||
}
|
||||
|
||||
/// Returns whether at least one run-local continuity gap remains unresolved.
|
||||
pub(crate) const fn continuity_has_open_gaps(&self) -> bool {
|
||||
return self.continuity_has_open_gaps;
|
||||
}
|
||||
|
||||
/// Returns whether currently Active sources still cover the complete configured future `TargetCoverage`.
|
||||
pub(crate) const fn future_target_coverage(&self) -> bool {
|
||||
return self.future_target_coverage;
|
||||
}
|
||||
|
||||
/// Returns a copy carrying whether every terminal Failed source has a reconciled source-loss gap.
|
||||
pub(crate) const fn with_failed_source_losses_reconciled(mut self, failed_source_losses_reconciled: bool) -> Self {
|
||||
self.failed_source_losses_reconciled = failed_source_losses_reconciled;
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Returns whether every terminal Failed source has a reconciled source-loss gap.
|
||||
pub(crate) const fn failed_source_losses_reconciled(&self) -> bool {
|
||||
return self.failed_source_losses_reconciled;
|
||||
}
|
||||
|
||||
/// Returns the configured logical source count carried by this private projection.
|
||||
pub(crate) const fn source_total(&self) -> usize {
|
||||
return self.source_total;
|
||||
@@ -159,6 +219,11 @@ impl crate::RawTransactionIngestProcessingFrontierProjection {
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub struct RawTransactionIngestSnapshot {
|
||||
worker: ksp_worker_api::WorkerSnapshot,
|
||||
continuity_frontier_slot: std::option::Option<u64>,
|
||||
continuity_has_open_gaps: bool,
|
||||
continuity_policy_observed: bool,
|
||||
failed_source_losses_reconciled: bool,
|
||||
future_target_coverage: bool,
|
||||
admission_queue_capacity: usize,
|
||||
admission_queue_depth: usize,
|
||||
persistence_concurrency: usize,
|
||||
@@ -488,6 +553,11 @@ impl crate::RawTransactionIngestSnapshotPublisher {
|
||||
);
|
||||
let snapshot = crate::RawTransactionIngestSnapshot {
|
||||
worker,
|
||||
continuity_frontier_slot: std::option::Option::None,
|
||||
continuity_has_open_gaps: false,
|
||||
continuity_policy_observed: false,
|
||||
failed_source_losses_reconciled: false,
|
||||
future_target_coverage: false,
|
||||
admission_queue_capacity: settings.admission_queue_capacity(),
|
||||
admission_queue_depth: 0,
|
||||
persistence_concurrency: settings.persistence_concurrency(),
|
||||
@@ -527,14 +597,7 @@ impl crate::RawTransactionIngestSnapshotPublisher {
|
||||
self.snapshot.worker.kind().clone(),
|
||||
self.snapshot.worker.sequence(),
|
||||
state,
|
||||
health_for_state(
|
||||
state,
|
||||
self.snapshot.worker.health(),
|
||||
self.snapshot.source_total,
|
||||
self.snapshot.source_active,
|
||||
self.snapshot.source_reconnecting,
|
||||
self.snapshot.source_failed,
|
||||
),
|
||||
health_for_state(state, self.snapshot.worker.health(), &self.snapshot),
|
||||
ksp_worker_api::WorkerActivity::Idle,
|
||||
);
|
||||
self.snapshot.worker = worker;
|
||||
@@ -611,6 +674,11 @@ impl crate::RawTransactionIngestSnapshotPublisher {
|
||||
in_flight_persistence: usize,
|
||||
projection: crate::RawTransactionIngestProcessingFrontierProjection,
|
||||
) -> ksp_core_lib::Result<()> {
|
||||
self.snapshot.continuity_frontier_slot = projection.continuity_frontier_slot();
|
||||
self.snapshot.continuity_has_open_gaps = projection.continuity_has_open_gaps();
|
||||
self.snapshot.continuity_policy_observed = projection.continuity_policy_observed();
|
||||
self.snapshot.failed_source_losses_reconciled = projection.failed_source_losses_reconciled();
|
||||
self.snapshot.future_target_coverage = projection.future_target_coverage();
|
||||
self.snapshot.hydration_pending = projection.hydration_pending();
|
||||
self.snapshot.processing_frontier_slot = projection.processing_frontier_slot();
|
||||
self.snapshot.oldest_pending_slot = projection.oldest_pending_slot();
|
||||
@@ -737,14 +805,7 @@ impl crate::RawTransactionIngestSnapshotPublisher {
|
||||
self.snapshot.worker.kind().clone(),
|
||||
sequence,
|
||||
state,
|
||||
health_for_state(
|
||||
state,
|
||||
self.snapshot.worker.health(),
|
||||
self.snapshot.source_total,
|
||||
self.snapshot.source_active,
|
||||
self.snapshot.source_reconnecting,
|
||||
self.snapshot.source_failed,
|
||||
),
|
||||
health_for_state(state, self.snapshot.worker.health(), &self.snapshot),
|
||||
activity_for_state(state, admission_queue_depth, in_flight_persistence, self.snapshot.hydration_pending, self.snapshot.source_state),
|
||||
);
|
||||
self.snapshot.worker = worker;
|
||||
@@ -799,15 +860,35 @@ fn checked_optional_counter(current: u64, increment: bool, field: &'static str)
|
||||
fn health_for_state(
|
||||
state: ksp_worker_api::WorkerState,
|
||||
previous: ksp_worker_api::WorkerHealth,
|
||||
source_total: usize,
|
||||
source_active: usize,
|
||||
source_reconnecting: usize,
|
||||
source_failed: usize,
|
||||
snapshot: &crate::RawTransactionIngestSnapshot,
|
||||
) -> ksp_worker_api::WorkerHealth {
|
||||
if state == ksp_worker_api::WorkerState::Running && snapshot.continuity_policy_observed {
|
||||
if snapshot.source_reconnecting > 0
|
||||
|| snapshot.continuity_has_open_gaps
|
||||
|| snapshot.continuity_frontier_slot != snapshot.processing_frontier_slot
|
||||
|| !snapshot.future_target_coverage
|
||||
{
|
||||
return ksp_worker_api::WorkerHealth::Unhealthy;
|
||||
}
|
||||
if snapshot.source_total > 0 && snapshot.source_active == snapshot.source_total {
|
||||
return ksp_worker_api::WorkerHealth::Healthy;
|
||||
}
|
||||
if snapshot.source_total > 0
|
||||
&& snapshot.source_active < snapshot.source_total
|
||||
&& snapshot.source_failed > 0
|
||||
&& snapshot.failed_source_losses_reconciled
|
||||
&& snapshot.source_failed == snapshot.source_total - snapshot.source_active
|
||||
{
|
||||
return ksp_worker_api::WorkerHealth::Degraded;
|
||||
}
|
||||
return ksp_worker_api::WorkerHealth::Unhealthy;
|
||||
}
|
||||
return match state {
|
||||
ksp_worker_api::WorkerState::Running if source_failed > 0 => ksp_worker_api::WorkerHealth::Unhealthy,
|
||||
ksp_worker_api::WorkerState::Running if source_reconnecting > 0 => ksp_worker_api::WorkerHealth::Degraded,
|
||||
ksp_worker_api::WorkerState::Running if source_total > 0 && source_active < source_total => ksp_worker_api::WorkerHealth::Degraded,
|
||||
ksp_worker_api::WorkerState::Running if snapshot.source_failed > 0 => ksp_worker_api::WorkerHealth::Unhealthy,
|
||||
ksp_worker_api::WorkerState::Running if snapshot.source_reconnecting > 0 => ksp_worker_api::WorkerHealth::Degraded,
|
||||
ksp_worker_api::WorkerState::Running if snapshot.source_total > 0 && snapshot.source_active < snapshot.source_total => {
|
||||
ksp_worker_api::WorkerHealth::Degraded
|
||||
},
|
||||
ksp_worker_api::WorkerState::Running => ksp_worker_api::WorkerHealth::Healthy,
|
||||
ksp_worker_api::WorkerState::Stopping | ksp_worker_api::WorkerState::Stopped => previous,
|
||||
ksp_worker_api::WorkerState::Faulted(_) => ksp_worker_api::WorkerHealth::Unhealthy,
|
||||
|
||||
Reference in New Issue
Block a user