()
| 209 | /// Tauri application entry point |
| 210 | #[cfg_attr(mobile, tauri::mobile_entry_point)] |
| 211 | pub async fn run() { |
| 212 | let startup_started = Instant::now(); |
| 213 | let startup_trace_id = SystemTime::now() |
| 214 | .duration_since(UNIX_EPOCH) |
| 215 | .map(|duration| format!("desktop-{}", duration.as_millis())) |
| 216 | .unwrap_or_else(|_| "desktop-unknown".to_string()); |
| 217 | let startup_trace = DesktopStartupTrace::new(startup_trace_id.clone(), startup_started); |
| 218 | startup_trace.record_phase("native_process_start", "native"); |
| 219 | let mut startup_timings = TimingCollector::default(); |
| 220 | let in_debug = cfg!(debug_assertions) || std::env::var("DEBUG").unwrap_or_default() == "1"; |
| 221 | let log_config = logging::LogConfig::new(in_debug); |
| 222 | let log_targets = logging::build_log_targets(&log_config); |
| 223 | let session_log_dir = log_config.session_log_dir.clone(); |
| 224 | crash_diagnostics::initialize_run_state(session_log_dir.clone(), &startup_trace_id); |
| 225 | setup_panic_hook(); |
| 226 | |
| 227 | // Install the rustls ring CryptoProvider as the process-level default early, |
| 228 | // so that all subsequent TLS operations (relay_client, reqwest, tokio-tungstenite) |
| 229 | // reuse the same provider instead of each attempting their own install_default(). |
| 230 | // This is a no-op on non-Windows platforms where tokio-tungstenite handles it. |
| 231 | bitfun_core::service::remote_connect::ensure_rustls_crypto_provider(); |
| 232 | |
| 233 | eprintln!("=== BitFun Desktop Starting ==="); |
| 234 | |
| 235 | let step_started = Instant::now(); |
| 236 | if let Err(e) = bitfun_core::service::config::initialize_global_config().await { |
| 237 | log::error!("Failed to initialize global config service: {}", e); |
| 238 | return; |
| 239 | } |
| 240 | startup_timings.record_elapsed("initialize_global_config", step_started); |
| 241 | startup_trace.record_elapsed_step("native_pre_tauri", "initialize_global_config", step_started); |
| 242 | |
| 243 | // Initialize global I18nService so bot/remote-connect language is always in sync. |
| 244 | { |
| 245 | use bitfun_core::service::config::get_global_config_service; |
| 246 | use bitfun_core::service::i18n::initialize_global_i18n_service; |
| 247 | let step_started = Instant::now(); |
| 248 | match get_global_config_service().await { |
| 249 | Ok(config_service) => { |
| 250 | if let Err(e) = initialize_global_i18n_service(Some(config_service)).await { |
| 251 | log::error!("Failed to initialize global I18nService: {}", e); |
| 252 | } |
| 253 | } |
| 254 | Err(e) => { |
| 255 | log::error!("Failed to get config service for I18nService init: {}", e); |
| 256 | } |
| 257 | } |
| 258 | startup_timings.record_elapsed("initialize_global_i18n_service", step_started); |
| 259 | startup_trace.record_elapsed_step( |
| 260 | "native_pre_tauri", |
| 261 | "initialize_global_i18n_service", |
| 262 | step_started, |
| 263 | ); |
| 264 | } |
| 265 | |
| 266 | let step_started = Instant::now(); |
| 267 | let startup_log_level = resolve_runtime_log_level(log_config.level).await; |
| 268 | startup_trace.record_elapsed_step( |
no test coverage detected