// file: crates/ksp-app-solprices-desk/src/app_state.rs // version: 6 //! Shared backend state owned by the SOL Prices Desk Tauri application. /// Shared SOL Prices Desk application state managed by Tauri. pub(crate) struct AppState { config_management: ksp_config_lib::ConfigManagement, logging_runtime: std::sync::Mutex, market_price_runtime: crate::MarketPriceRuntime, splash_settings: crate::SplashSettings, splash_sequence_started: std::sync::atomic::AtomicBool, } impl crate::AppState { /// Initializes Config ownership, composite-managed Logging and the provider-neutral market-price runtime. pub(crate) fn initialize(arguments: &[std::ffi::OsString]) -> ksp_core_lib::Result { let config_management = crate::config_management(arguments); let config_management = match config_management { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let runtime_identity = crate::launch_identity(); let runtime_identity = match runtime_identity { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let logging_startup = crate::initialize_logging(&config_management, &runtime_identity); let logging_startup = match logging_startup { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let offchain_transport_startup = crate::initialize_offchain_transport(&config_management); let offchain_transport_startup = match offchain_transport_startup { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let market_price_runtime = crate::MarketPriceRuntime::new(offchain_transport_startup); let market_price_runtime = match market_price_runtime { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let splash_settings = crate::SplashSettings::load(); let splash_settings = match splash_settings { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => { ksp_logging_lib::warn!(target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_WINDOWS, error_domain = error.code().domain(), error_code = error.code().code(), "managed splash timings are invalid; using transient in-memory defaults"); crate::SplashSettings::fallback() }, }; ksp_logging_lib::debug!(target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_WINDOWS, minimum_ms = splash_settings.minimum_ms(), minimum_source = splash_settings.minimum_source(), fade_in_ms = splash_settings.fade_in_ms(), fade_in_source = splash_settings.fade_in_source(), fade_out_ms = splash_settings.fade_out_ms(), fade_out_source = splash_settings.fade_out_source(), expected_backend_lifecycle_ms = splash_settings.expected_backend_lifecycle_ms(), "resolved SOL Prices Desk splash timings"); return std::result::Result::Ok(Self { config_management, logging_runtime: std::sync::Mutex::new(LoggingRuntimeState { guard: logging_startup.guard, active_profile_id: logging_startup.active_profile_id, fallback_active: logging_startup.fallback_active, startup_diagnostic: logging_startup.startup_diagnostic, }), market_price_runtime, splash_settings, splash_sequence_started: std::sync::atomic::AtomicBool::new(false), }); } /// Lists the current provider-neutral market-price rows without triggering network refresh. pub(crate) fn list_market_prices(&self) -> ksp_core_lib::Result> { return self.market_price_runtime.list_rows(); } /// Refreshes one provider by opaque identifier and returns its updated safe row projection. pub(crate) async fn refresh_market_price(&self, provider_id: String) -> ksp_core_lib::Result { return self.market_price_runtime.refresh_one(provider_id).await; } /// Refreshes a selected provider set in deterministic request order and returns only safe updated rows/counts. pub(crate) async fn refresh_market_prices( &self, request: crate::MarketPriceRefreshManyRequestDto, ) -> ksp_core_lib::Result { return self.market_price_runtime.refresh_many(request.into_provider_ids()).await; } /// Refreshes every configured provider in the deterministic order owned by Off-chain Transport. pub(crate) async fn refresh_all_market_prices(&self) -> ksp_core_lib::Result { return self.market_price_runtime.refresh_all().await; } /// Builds the safe runtime status exposed by the SOL Prices Desk shell. pub(crate) fn runtime_status(&self) -> ksp_core_lib::Result { let document_count = self.config_management.engine().registry().descriptors().count(); let document_count = u32::try_from(document_count); let document_count = match document_count { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => { return std::result::Result::Err( ksp_core_lib::Error::new( crate::ERROR_CODE_APP_STATE_INVALID, "Config registry contains too many descriptors for the SOL Prices Desk runtime DTO", ) .with_source(error), ); }, }; let provider_counts = self.market_price_runtime.provider_counts(); let (provider_count, ready_provider_count, unavailable_provider_count) = match provider_counts { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let runtime = self.logging_runtime.lock(); let runtime = match runtime { 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, "SOL Prices Desk Logging runtime state lock is poisoned", )); }, }; let _keep_guard_alive = &runtime.guard; let startup = self.market_price_runtime.startup(); let offchain = startup.resolved(); return std::result::Result::Ok(crate::MarketPriceRuntimeStatusDto { active_composite_profile: startup.composite_profile_id().to_owned(), active_logging_profile: runtime.active_profile_id.clone(), active_offchain_profile: offchain.profile_id().to_owned(), application_version: env!("CARGO_PKG_VERSION").to_owned(), config_document_count: document_count, fallback_logging_active: runtime.fallback_active, provider_count, ready_provider_count, shell_phase: "pre.007-ux-instrumentation".to_owned(), startup_diagnostic: runtime.startup_diagnostic.clone(), unavailable_provider_count, }); } /// Returns the resolved splash timings captured during application bootstrap. #[must_use] pub(crate) const fn splash_settings(&self) -> crate::SplashSettings { return self.splash_settings; } /// Marks the one-shot splash lifecycle as started and reports whether this caller won the transition. pub(crate) fn begin_splash_sequence(&self) -> bool { return self .splash_sequence_started .compare_exchange(false, true, std::sync::atomic::Ordering::AcqRel, std::sync::atomic::Ordering::Acquire) .is_ok(); } } struct LoggingRuntimeState { guard: ksp_logging_lib::LoggingGuard, active_profile_id: std::option::Option, fallback_active: bool, startup_diagnostic: std::option::Option, }