0.3.15-pre.010-fix.001

This commit is contained in:
2026-09-15 05:53:36 +02:00
parent 9fd51c5a41
commit e919945d1e
20 changed files with 1013 additions and 28 deletions

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-raw-transaction-ingest-desk/src/route_runtime.rs
// version: 5
// version: 6
//! Multi-route Store and independent Worker lifecycle owned by Raw Transaction Ingest Desk.
@@ -8,6 +8,7 @@ const STORE_RECLAIM_POLL_INTERVAL: std::time::Duration = std::time::Duration::fr
const STORE_RECLAIM_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(1);
struct RouteRuntimeInner {
last_monitoring: std::vec::Vec<crate::RawIngestRouteMonitoringDto>,
last_terminals: std::vec::Vec<crate::RawIngestRouteRuntimeDto>,
network: std::option::Option<String>,
next_sequence: u64,
@@ -28,6 +29,7 @@ impl crate::RouteRuntimeState {
pub(crate) fn new() -> Self {
return Self {
inner: std::sync::Mutex::new(RouteRuntimeInner {
last_monitoring: std::vec::Vec::new(),
last_terminals: std::vec::Vec::new(),
network: std::option::Option::None,
next_sequence: 0,
@@ -99,9 +101,11 @@ impl crate::RouteRuntimeState {
route_id: prepared.route_id,
};
if inner.network.is_none() {
inner.last_monitoring.clear();
inner.last_terminals.clear();
inner.network = std::option::Option::Some(prepared.network.clone());
}
inner.last_monitoring.retain(|status| return !identity.matches_monitoring(status));
inner.last_terminals.retain(|terminal| return !identity.matches_dto(terminal));
inner.next_sequence = sequence;
if needs_store_open {
@@ -196,7 +200,12 @@ impl crate::RouteRuntimeState {
return std::result::Result::Ok(std::option::Option::None);
}
fn finish(&self, token: u64, terminal: crate::RawIngestRouteRuntimeDto) -> ksp_core_lib::Result<std::option::Option<std::sync::Arc<ksp_store_lib::Store>>> {
fn finish(
&self,
token: u64,
terminal: crate::RawIngestRouteRuntimeDto,
monitoring: std::option::Option<crate::RawIngestRouteMonitoringDto>,
) -> ksp_core_lib::Result<std::option::Option<std::sync::Arc<ksp_store_lib::Store>>> {
let inner = self.inner.lock();
let mut inner = match inner {
std::result::Result::Ok(value) => value,
@@ -209,6 +218,10 @@ impl crate::RouteRuntimeState {
}
inner.last_terminals.retain(|previous| return previous.profile_id != terminal.profile_id || previous.route_id != terminal.route_id);
inner.last_terminals.push(terminal);
if let std::option::Option::Some(status) = monitoring {
inner.last_monitoring.retain(|previous| return previous.profile_id != status.profile_id || previous.route_id != status.route_id);
inner.last_monitoring.push(status);
}
if inner.routes.is_empty() {
let store = inner.store.take();
if store.is_some() {
@@ -235,6 +248,30 @@ impl crate::RouteRuntimeState {
}
}
/// Returns complete latest-value monitoring projections for active and recent terminal routes in the current runtime session.
pub(crate) fn monitoring_statuses(&self) -> ksp_core_lib::Result<std::vec::Vec<crate::RawIngestRouteMonitoringDto>> {
let inner = self.inner.lock();
let inner = match inner {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return std::result::Result::Err(runtime_lock_error()),
};
let mut values = inner.last_monitoring.clone();
for slot in &inner.routes {
if let RouteRuntimeSlot::Active { handle, identity, .. } = slot {
let snapshot = handle.snapshot_source().current();
let runtime = identity.dto(project_worker_state(snapshot.worker_snapshot().state()));
let projected = crate::project_route_monitoring(&runtime, &snapshot);
let projected = match projected {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
values.retain(|previous| return previous.profile_id != projected.profile_id || previous.route_id != projected.route_id);
values.push(projected);
}
}
return std::result::Result::Ok(values);
}
/// Requests cooperative Stop for one exact logical route and waits for its Worker cleanup.
pub(crate) async fn stop_and_wait(&self, request: &crate::RawIngestRouteStopRequestDto) -> ksp_core_lib::Result<crate::RawIngestRouteRuntimeDto> {
let target = self.stop_target(request);
@@ -389,6 +426,18 @@ impl crate::RouteRuntimeLaunch {
return self.acknowledgement.clone();
}
/// Returns the complete safe logical route identity used to project Worker monitoring snapshots.
#[must_use]
pub(crate) fn monitoring_identity(&self) -> crate::RawIngestRouteRuntimeDto {
return self.acknowledgement.clone();
}
/// Returns an independent latest-value source for frontend-safe monitoring relay.
#[must_use]
pub(crate) fn monitoring_source(&self) -> ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestSnapshotSource {
return self.handle.snapshot_source();
}
/// Waits for this Worker terminal state, removes only its route and closes Store only after the final same-network route terminates.
pub(crate) async fn monitor(self) {
let terminal = self.handle.wait_terminal().await;
@@ -415,7 +464,22 @@ impl crate::RouteRuntimeLaunch {
};
let mut terminal = self.acknowledgement;
terminal.state = terminal_state;
let store = self.runtime_state.finish(self.token, terminal);
let snapshot = self.handle.snapshot_source().current();
let monitoring = crate::project_route_monitoring(&terminal, &snapshot);
let monitoring = match monitoring {
std::result::Result::Ok(value) => std::option::Option::Some(value),
std::result::Result::Err(error) => {
ksp_logging_lib::warn!(
target: crate::TRACING_TARGET,
domain = crate::TRACING_DOMAIN_ROUTE_RUNTIME,
error_domain = error.code().domain(),
error_code = error.code().code(),
"Raw Transaction Ingest Desk could not retain terminal route monitoring projection"
);
std::option::Option::None
},
};
let store = self.runtime_state.finish(self.token, terminal, monitoring);
let store = match store {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
@@ -592,6 +656,10 @@ impl RouteRuntimeIdentity {
fn matches_dto(&self, value: &crate::RawIngestRouteRuntimeDto) -> bool {
return self.profile_id == value.profile_id && self.route_id == value.route_id;
}
fn matches_monitoring(&self, value: &crate::RawIngestRouteMonitoringDto) -> bool {
return self.profile_id == value.profile_id && self.route_id == value.route_id;
}
}
enum RouteStopTarget {