v0.3.15-pre.008
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-raw-transaction-ingest-desk/src/app_state.rs
|
||||
// version: 3
|
||||
// version: 4
|
||||
|
||||
//! Shared backend state owned by the Raw Transaction Ingest Desk Tauri application.
|
||||
|
||||
@@ -9,6 +9,7 @@ pub(crate) struct AppState {
|
||||
config_management: ksp_config_lib::ConfigManagement,
|
||||
inventory_generation: std::sync::Mutex<u32>,
|
||||
logging_runtime: std::sync::Mutex<LoggingRuntimeState>,
|
||||
route_runtime: std::sync::Arc<crate::RouteRuntimeState>,
|
||||
splash_settings: crate::SplashSettings,
|
||||
splash_sequence_started: std::sync::atomic::AtomicBool,
|
||||
}
|
||||
@@ -55,6 +56,7 @@ impl crate::AppState {
|
||||
fallback_active: logging_startup.fallback_active,
|
||||
startup_diagnostic: logging_startup.startup_diagnostic,
|
||||
}),
|
||||
route_runtime: std::sync::Arc::new(crate::RouteRuntimeState::new()),
|
||||
splash_settings,
|
||||
splash_sequence_started: std::sync::atomic::AtomicBool::new(false),
|
||||
});
|
||||
@@ -113,6 +115,31 @@ impl crate::AppState {
|
||||
return crate::validate_route_start(&self.config_management, generation, request);
|
||||
}
|
||||
|
||||
/// Starts one real mono-route Store + Worker runtime after repeating the complete Start-time revalidation.
|
||||
pub(crate) async fn start_route(&self, request: &crate::RawIngestRouteStartRequestDto) -> ksp_core_lib::Result<crate::RouteRuntimeLaunch> {
|
||||
let generation = self.inventory_generation.lock();
|
||||
let generation = match generation {
|
||||
std::result::Result::Ok(value) => *value,
|
||||
std::result::Result::Err(_) => {
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_APP_STATE_LOCK_FAILED,
|
||||
"Raw Transaction Ingest Desk route inventory generation lock is poisoned",
|
||||
));
|
||||
},
|
||||
};
|
||||
let prepared = crate::prepare_route_start(&self.config_management, generation, request);
|
||||
let prepared = match prepared {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
return crate::start_route_runtime(std::sync::Arc::clone(&self.route_runtime), prepared).await;
|
||||
}
|
||||
|
||||
/// Requests cooperative Stop and waits until the Worker is terminal and Store cleanup has released the mono-route slot.
|
||||
pub(crate) async fn stop_route(&self) -> ksp_core_lib::Result<crate::RawIngestRouteRuntimeDto> {
|
||||
return self.route_runtime.stop_and_wait().await;
|
||||
}
|
||||
|
||||
/// Builds the safe scaffold status exposed by the shell.
|
||||
pub(crate) fn shell_status(&self) -> ksp_core_lib::Result<crate::ShellStatusDto> {
|
||||
let document_count = self.config_management.engine().registry().descriptors().count();
|
||||
@@ -146,7 +173,7 @@ impl crate::AppState {
|
||||
application_version: env!("CARGO_PKG_VERSION").to_owned(),
|
||||
config_document_count: document_count,
|
||||
fallback_logging_active: runtime.fallback_active,
|
||||
shell_phase: "pre.007-start-resource-revalidation".to_owned(),
|
||||
shell_phase: "pre.008-mono-route-runtime".to_owned(),
|
||||
startup_diagnostic: runtime.startup_diagnostic.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-raw-transaction-ingest-desk/src/constants.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
//! Application-owned tracing targets and Config component identifiers.
|
||||
|
||||
@@ -21,6 +21,8 @@ pub(crate) const TRACING_DOMAIN_BOOTSTRAP: &str = "raw_transaction_ingest.bootst
|
||||
pub(crate) const TRACING_DOMAIN_FRONTEND: &str = "frontend";
|
||||
/// Structured domain used while rebuilding Config-only route inventory.
|
||||
pub(crate) const TRACING_DOMAIN_INVENTORY: &str = "raw_transaction_ingest.inventory";
|
||||
/// Structured domain used by mono-route Store and Worker lifecycle operations.
|
||||
pub(crate) const TRACING_DOMAIN_ROUTE_RUNTIME: &str = "raw_transaction_ingest.route_runtime";
|
||||
/// Structured domain used while revalidating future Start requests and reconstructing route resources.
|
||||
pub(crate) const TRACING_DOMAIN_ROUTE_START: &str = "raw_transaction_ingest.route_start";
|
||||
/// Structured domain used by the Raw Transaction Ingest Desk shell.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-raw-transaction-ingest-desk/src/dto_route.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
//! Safe route-identity, Config-composability and lifecycle DTOs for Raw Transaction Ingest Desk.
|
||||
|
||||
@@ -129,6 +129,25 @@ pub(crate) struct RawIngestRouteStartValidationDto {
|
||||
pub(crate) route_id: crate::RawIngestRouteId,
|
||||
}
|
||||
|
||||
/// Safe mono-route runtime acknowledgement containing only logical identity and lifecycle state.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_raw_transaction_ingest_desk/dto_route/RawIngestRouteRuntimeDto.ts")]
|
||||
pub(crate) struct RawIngestRouteRuntimeDto {
|
||||
/// Confirmed/finalized commitment bound to the active Worker.
|
||||
pub(crate) commitment: crate::RawIngestCommitment,
|
||||
/// Inventory generation revalidated before Store opening.
|
||||
pub(crate) inventory_generation: u32,
|
||||
/// Logical network bound identically to Store and Worker.
|
||||
pub(crate) network: String,
|
||||
/// Safe logical network-profile identifier.
|
||||
pub(crate) profile_id: String,
|
||||
/// Exact logical route owned by the mono-route Worker.
|
||||
pub(crate) route_id: crate::RawIngestRouteId,
|
||||
/// Safe application-owned projection of current Worker lifecycle.
|
||||
pub(crate) state: crate::RawIngestRouteState,
|
||||
}
|
||||
|
||||
/// Stable application-owned route families used only for safe presentation and orchestration.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-raw-transaction-ingest-desk/src/errors.rs
|
||||
// version: 3
|
||||
// version: 4
|
||||
|
||||
//! Stable Raw Transaction Ingest Desk application error codes.
|
||||
|
||||
@@ -26,6 +26,23 @@ pub(crate) const ERROR_CODE_ROUTE_INVENTORY_INVALID: ksp_core_lib::ErrorCode =
|
||||
/// Exact Start-time Transport resources cannot be reconstructed safely.
|
||||
pub(crate) const ERROR_CODE_ROUTE_START_PREPARATION_FAILED: ksp_core_lib::ErrorCode =
|
||||
ksp_core_lib::ErrorCode::new("raw_transaction_ingest_desk", "route_start_preparation_failed");
|
||||
/// A mono-route Worker runtime already owns the application slot.
|
||||
pub(crate) const ERROR_CODE_ROUTE_RUNTIME_ACTIVE: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("raw_transaction_ingest_desk", "route_runtime_active");
|
||||
/// No mono-route Worker runtime is currently active.
|
||||
pub(crate) const ERROR_CODE_ROUTE_RUNTIME_NOT_ACTIVE: ksp_core_lib::ErrorCode =
|
||||
ksp_core_lib::ErrorCode::new("raw_transaction_ingest_desk", "route_runtime_not_active");
|
||||
/// Store or Worker startup failed after Start-time route revalidation.
|
||||
pub(crate) const ERROR_CODE_ROUTE_RUNTIME_START_FAILED: ksp_core_lib::ErrorCode =
|
||||
ksp_core_lib::ErrorCode::new("raw_transaction_ingest_desk", "route_runtime_start_failed");
|
||||
/// The opened Store did not prove Ready before Worker launch.
|
||||
pub(crate) const ERROR_CODE_ROUTE_RUNTIME_STORE_NOT_READY: ksp_core_lib::ErrorCode =
|
||||
ksp_core_lib::ErrorCode::new("raw_transaction_ingest_desk", "route_runtime_store_not_ready");
|
||||
/// The Store could not be reclaimed or explicitly closed after Worker termination.
|
||||
pub(crate) const ERROR_CODE_ROUTE_RUNTIME_STORE_SHUTDOWN_FAILED: ksp_core_lib::ErrorCode =
|
||||
ksp_core_lib::ErrorCode::new("raw_transaction_ingest_desk", "route_runtime_store_shutdown_failed");
|
||||
/// The mono-route runtime reservation/handle state changed unexpectedly.
|
||||
pub(crate) const ERROR_CODE_ROUTE_RUNTIME_STATE_INVALID: ksp_core_lib::ErrorCode =
|
||||
ksp_core_lib::ErrorCode::new("raw_transaction_ingest_desk", "route_runtime_state_invalid");
|
||||
/// Start request references an inventory generation that is no longer current.
|
||||
pub(crate) const ERROR_CODE_ROUTE_START_STALE_INVENTORY: ksp_core_lib::ErrorCode =
|
||||
ksp_core_lib::ErrorCode::new("raw_transaction_ingest_desk", "stale_inventory");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-raw-transaction-ingest-desk/src/lib.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
//! Tauri desktop application scaffold for composing and supervising KSP live RAW transaction ingest routes.
|
||||
|
||||
@@ -16,6 +16,7 @@ mod errors;
|
||||
mod frontend_logging;
|
||||
mod logging_runtime;
|
||||
mod route_inventory;
|
||||
mod route_runtime;
|
||||
mod route_start;
|
||||
mod splash;
|
||||
mod tauri;
|
||||
@@ -57,6 +58,8 @@ pub(crate) use self::constants::TRACING_DOMAIN_BOOTSTRAP;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_FRONTEND;
|
||||
/// Structured domain used while rebuilding Config-only route inventory.
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_INVENTORY;
|
||||
/// Structured domain used by mono-route Store and Worker lifecycle operations.
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_ROUTE_RUNTIME;
|
||||
/// Structured domain used while revalidating future Start requests.
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_ROUTE_START;
|
||||
/// Structured domain used by the Raw Transaction Ingest Desk shell.
|
||||
@@ -89,6 +92,8 @@ pub(crate) use self::dto_route::RawIngestRouteFoundationDto;
|
||||
pub(crate) use self::dto_route::RawIngestRouteId;
|
||||
/// Complete deterministic Config-only route inventory.
|
||||
pub(crate) use self::dto_route::RawIngestRouteInventoryDto;
|
||||
/// Safe mono-route runtime acknowledgement containing only logical identity and lifecycle.
|
||||
pub(crate) use self::dto_route::RawIngestRouteRuntimeDto;
|
||||
/// Safe future Start request containing only logical route selection and inventory generation.
|
||||
pub(crate) use self::dto_route::RawIngestRouteStartRequestDto;
|
||||
/// Safe acknowledgement that exact Start-time resources were reconstructed without Worker launch.
|
||||
@@ -111,6 +116,18 @@ pub(crate) use self::errors::ERROR_CODE_FRONTEND_LOG_TARGET_INVALID;
|
||||
pub(crate) use self::errors::ERROR_CODE_LOGGING_BOOTSTRAP_FAILED;
|
||||
/// Config-only route inventory cannot be projected safely.
|
||||
pub(crate) use self::errors::ERROR_CODE_ROUTE_INVENTORY_INVALID;
|
||||
/// A mono-route Worker runtime already owns the application slot.
|
||||
pub(crate) use self::errors::ERROR_CODE_ROUTE_RUNTIME_ACTIVE;
|
||||
/// No mono-route Worker runtime is currently active.
|
||||
pub(crate) use self::errors::ERROR_CODE_ROUTE_RUNTIME_NOT_ACTIVE;
|
||||
/// Store or Worker startup failed after Start-time route revalidation.
|
||||
pub(crate) use self::errors::ERROR_CODE_ROUTE_RUNTIME_START_FAILED;
|
||||
/// The mono-route runtime reservation/handle state changed unexpectedly.
|
||||
pub(crate) use self::errors::ERROR_CODE_ROUTE_RUNTIME_STATE_INVALID;
|
||||
/// The opened Store did not prove Ready before Worker launch.
|
||||
pub(crate) use self::errors::ERROR_CODE_ROUTE_RUNTIME_STORE_NOT_READY;
|
||||
/// The Store could not be reclaimed or explicitly closed after Worker termination.
|
||||
pub(crate) use self::errors::ERROR_CODE_ROUTE_RUNTIME_STORE_SHUTDOWN_FAILED;
|
||||
/// Exact Start-time Transport resources cannot be reconstructed safely.
|
||||
pub(crate) use self::errors::ERROR_CODE_ROUTE_START_PREPARATION_FAILED;
|
||||
/// Start request references a stale inventory generation.
|
||||
@@ -137,6 +154,16 @@ pub(crate) use self::logging_runtime::launch_identity;
|
||||
pub(crate) use self::route_inventory::build_route_inventory;
|
||||
/// Rebuilds the route inventory from one already captured Config environment snapshot.
|
||||
pub(crate) use self::route_inventory::build_route_inventory_with_environment;
|
||||
/// Launch ownership for one mono-route Worker and its caller-owned Store.
|
||||
pub(crate) use self::route_runtime::RouteRuntimeLaunch;
|
||||
/// Shared mono-route runtime state admitting at most one starting or active Worker.
|
||||
pub(crate) use self::route_runtime::RouteRuntimeState;
|
||||
/// Opens Store and starts one exact route Worker after Start-time revalidation.
|
||||
pub(crate) use self::route_runtime::start_route_runtime;
|
||||
/// Fully revalidated Start preparation retaining Store settings and exact Worker resources.
|
||||
pub(crate) use self::route_start::PreparedRouteStart;
|
||||
/// Revalidates one Start request and retains its backend-only Store/Worker resources.
|
||||
pub(crate) use self::route_start::prepare_route_start;
|
||||
/// Revalidates one future Start request and reconstructs its exact Transport-owned Worker source contract without launch.
|
||||
pub(crate) use self::route_start::validate_route_start;
|
||||
/// Command emitted by Rust to the splash frontend.
|
||||
|
||||
396
crates/ksp-app-raw-transaction-ingest-desk/src/route_runtime.rs
Normal file
396
crates/ksp-app-raw-transaction-ingest-desk/src/route_runtime.rs
Normal file
@@ -0,0 +1,396 @@
|
||||
// file: crates/ksp-app-raw-transaction-ingest-desk/src/route_runtime.rs
|
||||
// version: 1
|
||||
|
||||
//! Mono-route Store and Worker lifecycle owned by Raw Transaction Ingest Desk.
|
||||
|
||||
const ROUTE_STOP_CLEANUP_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(2);
|
||||
const STORE_RECLAIM_POLL_INTERVAL: std::time::Duration = std::time::Duration::from_millis(5);
|
||||
const STORE_RECLAIM_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(1);
|
||||
|
||||
/// Shared mono-route runtime state. `pre.008` admits at most one active or starting Worker.
|
||||
pub(crate) struct RouteRuntimeState {
|
||||
inner: std::sync::Mutex<RouteRuntimeInner>,
|
||||
}
|
||||
|
||||
impl crate::RouteRuntimeState {
|
||||
/// Creates an idle mono-route runtime state.
|
||||
#[must_use]
|
||||
pub(crate) fn new() -> Self {
|
||||
return Self { inner: std::sync::Mutex::new(RouteRuntimeInner { next_sequence: 0, slot: RouteRuntimeSlot::Idle }) };
|
||||
}
|
||||
|
||||
fn reserve(&self, prepared: &crate::PreparedRouteStart) -> ksp_core_lib::Result<RouteRuntimeReservation> {
|
||||
let inner = self.inner.lock();
|
||||
let mut inner = match inner {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return std::result::Result::Err(runtime_lock_error()),
|
||||
};
|
||||
if !matches!(inner.slot, RouteRuntimeSlot::Idle) {
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_ROUTE_RUNTIME_ACTIVE,
|
||||
"Raw Transaction Ingest Desk already owns one mono-route Worker runtime",
|
||||
));
|
||||
}
|
||||
let sequence = inner.next_sequence.checked_add(1);
|
||||
let sequence = match sequence {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => {
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_ROUTE_RUNTIME_START_FAILED,
|
||||
"Raw Transaction Ingest Desk Worker sequence is exhausted",
|
||||
));
|
||||
},
|
||||
};
|
||||
let worker_id = ksp_worker_api::WorkerId::new(format!("raw-ingest-desk-{sequence}"));
|
||||
let worker_id = match worker_id {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(crate::ERROR_CODE_ROUTE_RUNTIME_START_FAILED, "Cannot create Raw Transaction Ingest Desk Worker identity")
|
||||
.with_source(error),
|
||||
);
|
||||
},
|
||||
};
|
||||
let identity = RouteRuntimeIdentity {
|
||||
commitment: prepared.commitment,
|
||||
inventory_generation: prepared.inventory_generation,
|
||||
network: prepared.network.clone(),
|
||||
profile_id: prepared.profile_id.clone(),
|
||||
route_id: prepared.route_id,
|
||||
};
|
||||
inner.next_sequence = sequence;
|
||||
inner.slot = RouteRuntimeSlot::Starting { token: sequence };
|
||||
return std::result::Result::Ok(RouteRuntimeReservation { identity, token: sequence, worker_id });
|
||||
}
|
||||
|
||||
fn activate(
|
||||
&self,
|
||||
reservation: &RouteRuntimeReservation,
|
||||
handle: ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestHandle,
|
||||
) -> ksp_core_lib::Result<crate::RawIngestRouteRuntimeDto> {
|
||||
let inner = self.inner.lock();
|
||||
let mut inner = match inner {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return std::result::Result::Err(runtime_lock_error()),
|
||||
};
|
||||
match &inner.slot {
|
||||
RouteRuntimeSlot::Starting { token } if *token == reservation.token => {},
|
||||
RouteRuntimeSlot::Idle | RouteRuntimeSlot::Starting { .. } | RouteRuntimeSlot::Active { .. } => {
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_ROUTE_RUNTIME_STATE_INVALID,
|
||||
"Raw Transaction Ingest Desk mono-route runtime reservation changed before Worker activation",
|
||||
));
|
||||
},
|
||||
}
|
||||
let state = project_worker_state(handle.snapshot_source().current().worker_snapshot().state());
|
||||
inner.slot = RouteRuntimeSlot::Active { handle, identity: reservation.identity.clone(), token: reservation.token };
|
||||
return std::result::Result::Ok(reservation.identity.dto(state));
|
||||
}
|
||||
|
||||
fn rollback(&self, token: u64) {
|
||||
let inner = self.inner.lock();
|
||||
let mut inner = match inner {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
if matches!(&inner.slot, RouteRuntimeSlot::Starting { token: current, .. } if *current == token) {
|
||||
inner.slot = RouteRuntimeSlot::Idle;
|
||||
}
|
||||
}
|
||||
|
||||
fn finish(&self, token: u64) {
|
||||
let inner = self.inner.lock();
|
||||
let mut inner = match inner {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
if matches!(&inner.slot, RouteRuntimeSlot::Active { token: current, .. } if *current == token) {
|
||||
inner.slot = RouteRuntimeSlot::Idle;
|
||||
}
|
||||
}
|
||||
|
||||
/// Requests cooperative Stop, waits for terminal Worker state and returns after the terminal monitor has released the mono-route slot.
|
||||
pub(crate) async fn stop_and_wait(&self) -> ksp_core_lib::Result<crate::RawIngestRouteRuntimeDto> {
|
||||
let active = {
|
||||
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()),
|
||||
};
|
||||
match &inner.slot {
|
||||
RouteRuntimeSlot::Active { handle, identity, .. } => std::result::Result::Ok((handle.clone(), identity.clone())),
|
||||
RouteRuntimeSlot::Idle | RouteRuntimeSlot::Starting { .. } => std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_ROUTE_RUNTIME_NOT_ACTIVE,
|
||||
"Raw Transaction Ingest Desk has no active mono-route Worker to stop",
|
||||
)),
|
||||
}
|
||||
};
|
||||
let (handle, identity) = match active {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let _first_stop_request = handle.request_stop();
|
||||
let terminal = handle.wait_terminal().await;
|
||||
let terminal = match terminal {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(crate::ERROR_CODE_ROUTE_RUNTIME_STATE_INVALID, "Cannot observe terminal Raw Transaction Ingest Desk Worker state")
|
||||
.with_source(error),
|
||||
);
|
||||
},
|
||||
};
|
||||
let started = std::time::Instant::now();
|
||||
loop {
|
||||
if self.is_idle()? {
|
||||
return std::result::Result::Ok(identity.dto(project_worker_state(terminal)));
|
||||
}
|
||||
if started.elapsed() >= ROUTE_STOP_CLEANUP_TIMEOUT {
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_ROUTE_RUNTIME_STORE_SHUTDOWN_FAILED,
|
||||
"Raw Transaction Ingest Desk terminal cleanup did not release the mono-route slot",
|
||||
));
|
||||
}
|
||||
tokio::time::sleep(STORE_RECLAIM_POLL_INTERVAL).await;
|
||||
}
|
||||
}
|
||||
|
||||
fn is_idle(&self) -> ksp_core_lib::Result<bool> {
|
||||
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()),
|
||||
};
|
||||
return std::result::Result::Ok(matches!(inner.slot, RouteRuntimeSlot::Idle));
|
||||
}
|
||||
}
|
||||
|
||||
/// Launch ownership returned only after Store readiness, Worker creation and handle installation have succeeded.
|
||||
pub(crate) struct RouteRuntimeLaunch {
|
||||
acknowledgement: crate::RawIngestRouteRuntimeDto,
|
||||
handle: ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestHandle,
|
||||
runtime_state: std::sync::Arc<crate::RouteRuntimeState>,
|
||||
store: std::sync::Arc<ksp_store_lib::Store>,
|
||||
token: u64,
|
||||
}
|
||||
|
||||
impl crate::RouteRuntimeLaunch {
|
||||
/// Returns the safe Start acknowledgement captured after the Worker handle was installed.
|
||||
#[must_use]
|
||||
pub(crate) fn acknowledgement(&self) -> crate::RawIngestRouteRuntimeDto {
|
||||
return self.acknowledgement.clone();
|
||||
}
|
||||
|
||||
/// Waits for terminal Worker state, explicitly closes Store after the Worker releases its `Arc`, then frees the mono-route slot.
|
||||
pub(crate) async fn monitor(self) {
|
||||
let terminal = self.handle.wait_terminal().await;
|
||||
match terminal {
|
||||
std::result::Result::Ok(state) => {
|
||||
ksp_logging_lib::info!(
|
||||
target: crate::TRACING_TARGET,
|
||||
domain = crate::TRACING_DOMAIN_ROUTE_RUNTIME,
|
||||
worker_state = state.code(),
|
||||
"Raw Transaction Ingest Desk mono-route Worker reached terminal state"
|
||||
);
|
||||
},
|
||||
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 terminal Worker wait failed"
|
||||
);
|
||||
},
|
||||
}
|
||||
let close = close_store_arc(self.store).await;
|
||||
if let std::result::Result::Err(error) = close {
|
||||
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 Store shutdown failed after terminal Worker"
|
||||
);
|
||||
}
|
||||
self.runtime_state.finish(self.token);
|
||||
}
|
||||
}
|
||||
|
||||
/// Opens one Store, starts one exact Worker route and atomically installs its handle in the mono-route application slot.
|
||||
pub(crate) async fn start_route_runtime(
|
||||
runtime_state: std::sync::Arc<crate::RouteRuntimeState>,
|
||||
prepared: crate::PreparedRouteStart,
|
||||
) -> ksp_core_lib::Result<crate::RouteRuntimeLaunch> {
|
||||
let reservation = runtime_state.reserve(&prepared);
|
||||
let reservation = match reservation {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let store = ksp_store_lib::Store::open(prepared.store_settings).await;
|
||||
let store = match store {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
runtime_state.rollback(reservation.token);
|
||||
return std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(crate::ERROR_CODE_ROUTE_RUNTIME_START_FAILED, "Cannot open Raw Transaction Ingest Desk Store runtime")
|
||||
.with_source(error),
|
||||
);
|
||||
},
|
||||
};
|
||||
let health = store.health().await;
|
||||
if health.state() != ksp_store_lib::StoreHealthState::Ready {
|
||||
let close = store.close().await;
|
||||
runtime_state.rollback(reservation.token);
|
||||
if let std::result::Result::Err(error) = close {
|
||||
return std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_ROUTE_RUNTIME_STORE_SHUTDOWN_FAILED,
|
||||
"Cannot close non-ready Raw Transaction Ingest Desk Store runtime",
|
||||
)
|
||||
.with_source(error),
|
||||
);
|
||||
}
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_ROUTE_RUNTIME_STORE_NOT_READY,
|
||||
"Raw Transaction Ingest Desk Store readiness probe did not prove Ready",
|
||||
));
|
||||
}
|
||||
let network = store.runtime_snapshot().network().clone();
|
||||
let settings = ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestSettings::with_defaults(network, reservation.worker_id.clone());
|
||||
let store = std::sync::Arc::new(store);
|
||||
let handle = ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestWorker::start_with_runtime_resources(
|
||||
settings,
|
||||
std::sync::Arc::clone(&store),
|
||||
prepared.runtime_resources,
|
||||
);
|
||||
let handle = match handle {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
let close = close_store_arc(store).await;
|
||||
runtime_state.rollback(reservation.token);
|
||||
if let std::result::Result::Err(close_error) = close {
|
||||
return std::result::Result::Err(close_error);
|
||||
}
|
||||
return std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(crate::ERROR_CODE_ROUTE_RUNTIME_START_FAILED, "Cannot start Raw Transaction Ingest Desk Worker runtime")
|
||||
.with_source(error),
|
||||
);
|
||||
},
|
||||
};
|
||||
let acknowledgement = runtime_state.activate(&reservation, handle.clone());
|
||||
let acknowledgement = match acknowledgement {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
let _stop_requested = handle.request_stop();
|
||||
let _terminal = handle.wait_terminal().await;
|
||||
let close = close_store_arc(store).await;
|
||||
runtime_state.rollback(reservation.token);
|
||||
if let std::result::Result::Err(close_error) = close {
|
||||
return std::result::Result::Err(close_error);
|
||||
}
|
||||
return std::result::Result::Err(error);
|
||||
},
|
||||
};
|
||||
ksp_logging_lib::info!(
|
||||
target: crate::TRACING_TARGET,
|
||||
domain = crate::TRACING_DOMAIN_ROUTE_RUNTIME,
|
||||
profile_id = reservation.identity.profile_id.as_str(),
|
||||
network = reservation.identity.network.as_str(),
|
||||
route_id = reservation.identity.route_id.as_str(),
|
||||
commitment = reservation.identity.commitment.as_str(),
|
||||
"Raw Transaction Ingest Desk mono-route Worker handle installed"
|
||||
);
|
||||
return std::result::Result::Ok(crate::RouteRuntimeLaunch { acknowledgement, handle, runtime_state, store, token: reservation.token });
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct RouteRuntimeIdentity {
|
||||
commitment: crate::RawIngestCommitment,
|
||||
inventory_generation: u32,
|
||||
network: String,
|
||||
profile_id: String,
|
||||
route_id: crate::RawIngestRouteId,
|
||||
}
|
||||
|
||||
impl RouteRuntimeIdentity {
|
||||
fn dto(&self, state: crate::RawIngestRouteState) -> crate::RawIngestRouteRuntimeDto {
|
||||
return crate::RawIngestRouteRuntimeDto {
|
||||
commitment: self.commitment,
|
||||
inventory_generation: self.inventory_generation,
|
||||
network: self.network.clone(),
|
||||
profile_id: self.profile_id.clone(),
|
||||
route_id: self.route_id,
|
||||
state,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
struct RouteRuntimeReservation {
|
||||
identity: RouteRuntimeIdentity,
|
||||
token: u64,
|
||||
worker_id: ksp_worker_api::WorkerId,
|
||||
}
|
||||
|
||||
enum RouteRuntimeSlot {
|
||||
Idle,
|
||||
Starting {
|
||||
token: u64,
|
||||
},
|
||||
Active {
|
||||
handle: ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestHandle,
|
||||
identity: RouteRuntimeIdentity,
|
||||
token: u64,
|
||||
},
|
||||
}
|
||||
|
||||
async fn close_store_arc(store: std::sync::Arc<ksp_store_lib::Store>) -> ksp_core_lib::Result<()> {
|
||||
let started = std::time::Instant::now();
|
||||
let mut store = store;
|
||||
loop {
|
||||
match std::sync::Arc::try_unwrap(store) {
|
||||
std::result::Result::Ok(value) => {
|
||||
let close = value.close().await;
|
||||
return match close {
|
||||
std::result::Result::Ok(()) => std::result::Result::Ok(()),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_ROUTE_RUNTIME_STORE_SHUTDOWN_FAILED,
|
||||
"Cannot close Raw Transaction Ingest Desk Store runtime",
|
||||
)
|
||||
.with_source(error),
|
||||
),
|
||||
};
|
||||
},
|
||||
std::result::Result::Err(shared) => {
|
||||
store = shared;
|
||||
},
|
||||
}
|
||||
if started.elapsed() >= STORE_RECLAIM_TIMEOUT {
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_ROUTE_RUNTIME_STORE_SHUTDOWN_FAILED,
|
||||
"Raw Transaction Ingest Desk Store remained shared after terminal Worker",
|
||||
));
|
||||
}
|
||||
tokio::time::sleep(STORE_RECLAIM_POLL_INTERVAL).await;
|
||||
}
|
||||
}
|
||||
|
||||
fn project_worker_state(state: ksp_worker_api::WorkerState) -> crate::RawIngestRouteState {
|
||||
return match state {
|
||||
ksp_worker_api::WorkerState::Created | ksp_worker_api::WorkerState::Starting => crate::RawIngestRouteState::Starting,
|
||||
ksp_worker_api::WorkerState::Running => crate::RawIngestRouteState::Running,
|
||||
ksp_worker_api::WorkerState::Stopping => crate::RawIngestRouteState::Stopping,
|
||||
ksp_worker_api::WorkerState::Stopped => crate::RawIngestRouteState::Stopped,
|
||||
ksp_worker_api::WorkerState::Faulted(_) => crate::RawIngestRouteState::Faulted,
|
||||
_ => crate::RawIngestRouteState::Faulted,
|
||||
};
|
||||
}
|
||||
|
||||
fn runtime_lock_error() -> ksp_core_lib::Error {
|
||||
return ksp_core_lib::Error::new(crate::ERROR_CODE_APP_STATE_LOCK_FAILED, "Raw Transaction Ingest Desk mono-route runtime state lock is poisoned");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "../unit_tests/route_runtime.rs"]
|
||||
mod tests;
|
||||
@@ -1,14 +1,32 @@
|
||||
// file: crates/ksp-app-raw-transaction-ingest-desk/src/route_start.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Start-time Config revalidation and Transport-resource reconstruction without Worker launch.
|
||||
//! Start-time Config revalidation and exact Transport/Store resource reconstruction for route validation and runtime launch.
|
||||
|
||||
/// Revalidates one future Start request against the current inventory generation and reconstructs the exact Worker source contract without starting it.
|
||||
pub(crate) fn validate_route_start(
|
||||
/// Fully revalidated Start preparation retaining backend-only Store settings and exact Worker runtime resources.
|
||||
pub(crate) struct PreparedRouteStart {
|
||||
/// Confirmed/finalized commitment validated by the exact route constructor.
|
||||
pub(crate) commitment: crate::RawIngestCommitment,
|
||||
/// Inventory generation proven current while this preparation was built.
|
||||
pub(crate) inventory_generation: u32,
|
||||
/// Logical network proven identical across Store and Transport.
|
||||
pub(crate) network: String,
|
||||
/// Logical network-profile identifier selected by the operator.
|
||||
pub(crate) profile_id: String,
|
||||
/// Logical route selected by the operator.
|
||||
pub(crate) route_id: crate::RawIngestRouteId,
|
||||
/// Backend-neutral Store settings resolved from Config and retained only in Rust.
|
||||
pub(crate) store_settings: ksp_store_lib::StoreSettings,
|
||||
/// Exact single-route Worker runtime resources reconstructed from typed Transport contracts.
|
||||
pub(crate) runtime_resources: ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources,
|
||||
}
|
||||
|
||||
/// Revalidates one Start request and retains the exact backend resources required for a later Worker launch.
|
||||
pub(crate) fn prepare_route_start(
|
||||
management: &ksp_config_lib::ConfigManagement,
|
||||
current_generation: u32,
|
||||
request: &crate::RawIngestRouteStartRequestDto,
|
||||
) -> ksp_core_lib::Result<crate::RawIngestRouteStartValidationDto> {
|
||||
) -> ksp_core_lib::Result<crate::PreparedRouteStart> {
|
||||
if current_generation == 0 || request.inventory_generation != current_generation {
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_ROUTE_START_STALE_INVENTORY,
|
||||
@@ -78,16 +96,17 @@ pub(crate) fn validate_route_start(
|
||||
));
|
||||
}
|
||||
let commitment = request.commitment.into_transport();
|
||||
let prepared = match request.route_id {
|
||||
let runtime_resources = match request.route_id {
|
||||
crate::RawIngestRouteId::YellowstoneHydrated => prepare_yellowstone(management, &environment, &composite, &transport, network, commitment),
|
||||
crate::RawIngestRouteId::StandardLogsHydrated => prepare_standard_logs(&transport, network, commitment),
|
||||
crate::RawIngestRouteId::StandardBlockDirect => prepare_standard_block(&transport, network, commitment),
|
||||
crate::RawIngestRouteId::HeliusTransactionHydrated => prepare_helius(management, &environment, &composite, &transport, network, commitment),
|
||||
crate::RawIngestRouteId::HttpBlockPolling => prepare_http_polling(&transport, network, commitment),
|
||||
};
|
||||
if let std::result::Result::Err(error) = prepared {
|
||||
return route_start_error("Cannot reconstruct Start-time Transport resources", error);
|
||||
}
|
||||
let runtime_resources = match runtime_resources {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return route_start_error("Cannot reconstruct Start-time Transport resources", error),
|
||||
};
|
||||
ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET,
|
||||
domain = crate::TRACING_DOMAIN_ROUTE_START,
|
||||
@@ -96,14 +115,36 @@ pub(crate) fn validate_route_start(
|
||||
route_id = request.route_id.as_str(),
|
||||
inventory_generation = request.inventory_generation,
|
||||
commitment = request.commitment.as_str(),
|
||||
"revalidated Start request and reconstructed exact Transport-owned Worker source contract without runtime I/O"
|
||||
"revalidated Start request and reconstructed exact Store/Transport-owned Worker launch resources"
|
||||
);
|
||||
return std::result::Result::Ok(crate::RawIngestRouteStartValidationDto {
|
||||
return std::result::Result::Ok(crate::PreparedRouteStart {
|
||||
commitment: request.commitment,
|
||||
inventory_generation: request.inventory_generation,
|
||||
network: network.to_owned(),
|
||||
profile_id: request.profile_id.clone(),
|
||||
route_id: request.route_id,
|
||||
store_settings: store.into_settings(),
|
||||
runtime_resources,
|
||||
});
|
||||
}
|
||||
|
||||
/// Revalidates one future Start request and destroys the reconstructed resources without opening Store or launching a Worker.
|
||||
pub(crate) fn validate_route_start(
|
||||
management: &ksp_config_lib::ConfigManagement,
|
||||
current_generation: u32,
|
||||
request: &crate::RawIngestRouteStartRequestDto,
|
||||
) -> ksp_core_lib::Result<crate::RawIngestRouteStartValidationDto> {
|
||||
let prepared = crate::prepare_route_start(management, current_generation, request);
|
||||
let prepared = match prepared {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
return std::result::Result::Ok(crate::RawIngestRouteStartValidationDto {
|
||||
commitment: prepared.commitment,
|
||||
inventory_generation: prepared.inventory_generation,
|
||||
network: prepared.network,
|
||||
profile_id: prepared.profile_id,
|
||||
route_id: prepared.route_id,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -111,7 +152,7 @@ fn prepare_standard_logs(
|
||||
transport: &ksp_config_lib::ResolvedTransportConfig,
|
||||
network: &str,
|
||||
commitment: ksp_onchain_transport_lib::SolanaCommitment,
|
||||
) -> ksp_core_lib::Result<()> {
|
||||
) -> ksp_core_lib::Result<ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources> {
|
||||
let endpoint =
|
||||
single_ws_endpoint(transport, network, ksp_onchain_transport_lib::WsProtocolKind::SolanaStandard, ksp_onchain_transport_lib::WsSubscriptionKind::Logs);
|
||||
let endpoint = match endpoint {
|
||||
@@ -139,15 +180,14 @@ fn prepare_standard_logs(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
std::mem::drop(source);
|
||||
return std::result::Result::Ok(());
|
||||
return std::result::Result::Ok(ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources::from_standard_logs_source(source));
|
||||
}
|
||||
|
||||
fn prepare_standard_block(
|
||||
transport: &ksp_config_lib::ResolvedTransportConfig,
|
||||
network: &str,
|
||||
commitment: ksp_onchain_transport_lib::SolanaCommitment,
|
||||
) -> ksp_core_lib::Result<()> {
|
||||
) -> ksp_core_lib::Result<ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources> {
|
||||
let endpoint =
|
||||
single_ws_endpoint(transport, network, ksp_onchain_transport_lib::WsProtocolKind::SolanaStandard, ksp_onchain_transport_lib::WsSubscriptionKind::Block);
|
||||
let endpoint = match endpoint {
|
||||
@@ -163,8 +203,7 @@ fn prepare_standard_block(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
std::mem::drop(source);
|
||||
return std::result::Result::Ok(());
|
||||
return std::result::Result::Ok(ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources::from_standard_block_source(source));
|
||||
}
|
||||
|
||||
fn prepare_helius(
|
||||
@@ -174,7 +213,7 @@ fn prepare_helius(
|
||||
base_transport: &ksp_config_lib::ResolvedTransportConfig,
|
||||
network: &str,
|
||||
commitment: ksp_onchain_transport_lib::SolanaCommitment,
|
||||
) -> ksp_core_lib::Result<()> {
|
||||
) -> ksp_core_lib::Result<ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources> {
|
||||
let transport = resolve_optional_transport(management, environment, composite, crate::COMPOSITE_COMPONENT_ID_TRANSPORT_HELIUS, network);
|
||||
let transport = match transport {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -214,8 +253,7 @@ fn prepare_helius(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
std::mem::drop(source);
|
||||
return std::result::Result::Ok(());
|
||||
return std::result::Result::Ok(ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources::from_helius_transaction_source(source));
|
||||
}
|
||||
|
||||
fn prepare_yellowstone(
|
||||
@@ -225,7 +263,7 @@ fn prepare_yellowstone(
|
||||
base_transport: &ksp_config_lib::ResolvedTransportConfig,
|
||||
network: &str,
|
||||
commitment: ksp_onchain_transport_lib::SolanaCommitment,
|
||||
) -> ksp_core_lib::Result<()> {
|
||||
) -> ksp_core_lib::Result<ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources> {
|
||||
let transport = resolve_optional_transport(management, environment, composite, crate::COMPOSITE_COMPONENT_ID_TRANSPORT_YELLOWSTONE, network);
|
||||
let transport = match transport {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -267,15 +305,14 @@ fn prepare_yellowstone(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
std::mem::drop(source);
|
||||
return std::result::Result::Ok(());
|
||||
return std::result::Result::Ok(ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources::new(source));
|
||||
}
|
||||
|
||||
fn prepare_http_polling(
|
||||
transport: &ksp_config_lib::ResolvedTransportConfig,
|
||||
network: &str,
|
||||
commitment: ksp_onchain_transport_lib::SolanaCommitment,
|
||||
) -> ksp_core_lib::Result<()> {
|
||||
) -> ksp_core_lib::Result<ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources> {
|
||||
let role = single_http_role(transport.http_settings(), network, &["getSlot", "getBlocksWithLimit", "getBlock"]);
|
||||
let role = match role {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -291,8 +328,7 @@ fn prepare_http_polling(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
std::mem::drop(source);
|
||||
return std::result::Result::Ok(());
|
||||
return std::result::Result::Ok(ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources::from_http_block_polling_source(source));
|
||||
}
|
||||
|
||||
fn resolve_optional_transport(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-raw-transaction-ingest-desk/src/tauri.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
//! Tauri runtime assembly for the KSP Raw Transaction Ingest desktop application.
|
||||
|
||||
@@ -80,6 +80,8 @@ fn configure_commands(builder: tauri::Builder<tauri::Wry>) -> tauri::Builder<tau
|
||||
get_route_inventory,
|
||||
get_runtime_status,
|
||||
splash_frontend_ready,
|
||||
start_route,
|
||||
stop_route,
|
||||
validate_route_start
|
||||
]);
|
||||
}
|
||||
@@ -141,6 +143,35 @@ async fn splash_frontend_ready(
|
||||
};
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn start_route(
|
||||
request: crate::RawIngestRouteStartRequestDto,
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
) -> std::result::Result<crate::RawIngestRouteRuntimeDto, crate::CommandErrorDto> {
|
||||
let launch = state.start_route(&request).await;
|
||||
let launch = match launch {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(project_command_error("start_route", crate::TRACING_DOMAIN_ROUTE_RUNTIME, &error));
|
||||
},
|
||||
};
|
||||
let acknowledgement = launch.acknowledgement();
|
||||
let monitor = tauri::async_runtime::spawn(async move {
|
||||
launch.monitor().await;
|
||||
});
|
||||
std::mem::drop(monitor);
|
||||
return std::result::Result::Ok(acknowledgement);
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn stop_route(state: tauri::State<'_, crate::AppState>) -> std::result::Result<crate::RawIngestRouteRuntimeDto, crate::CommandErrorDto> {
|
||||
let result = state.stop_route().await;
|
||||
return match result {
|
||||
std::result::Result::Ok(value) => std::result::Result::Ok(value),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(project_command_error("stop_route", crate::TRACING_DOMAIN_ROUTE_RUNTIME, &error)),
|
||||
};
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn validate_route_start(
|
||||
request: crate::RawIngestRouteStartRequestDto,
|
||||
|
||||
Reference in New Issue
Block a user