diff --git a/desktop/src-tauri/src/event_sync.rs b/desktop/src-tauri/src/event_sync.rs index d8dfe94b1..efd16489a 100644 --- a/desktop/src-tauri/src/event_sync.rs +++ b/desktop/src-tauri/src/event_sync.rs @@ -19,6 +19,24 @@ pub fn run_event_sync(app: &tauri::AppHandle, owner_keys: &nostr::Keys) { crate::managed_agents::reconcile::reconcile_agents_to_events(app, owner_keys); } +/// Spawn the best-effort event reconcile off the synchronous Tauri setup path. +/// +/// The owner keys are cloned before spawning so the task never touches the +/// `AppState::keys` mutex. The reconcile itself is still synchronous JSON, +/// SQLite, and signing work, so it runs on the blocking pool rather than an +/// async worker. +pub fn spawn_event_sync(app: tauri::AppHandle, owner_keys: nostr::Keys) { + tauri::async_runtime::spawn(async move { + if let Err(e) = tauri::async_runtime::spawn_blocking(move || { + run_event_sync(&app, &owner_keys); + }) + .await + { + eprintln!("buzz-desktop: event-sync: spawn_blocking failed: {e}"); + } + }); +} + /// Reconcile `personas.json` into the persona-event retention store. /// /// Must run AFTER `migrate_packs_to_teams` (depends on field renames being diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index 341c99d7b..def24183f 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -226,14 +226,13 @@ pub fn run() { resolve_persisted_identity(&app_handle, &state) .map_err(|e| -> Box { e.into() })?; - // Sync team-dir edits and reconcile persona/team events. Needs the - // resolved owner keys, so it runs after identity resolution. + // Snapshot owner keys after identity resolution; the best-effort + // event reconcile itself runs off the synchronous setup path below. let owner_keys = state .keys .lock() .map(|k| k.clone()) .map_err(|e| -> Box { e.to_string().into() })?; - event_sync::run_event_sync(&app_handle, &owner_keys); // Backfill the pinned persona snapshot for any pre-existing agent // that predates the record-authoritative-spawn cutover (persona_id @@ -332,6 +331,12 @@ pub fn run() { try_regenerate_nest(&app_handle); + // Sync team-dir edits and reconcile persona/team/agent events after + // setup can continue. It is best-effort retention backfill, unlike + // identity resolution above, so JSON/SQLite/signing work must not + // hold the boot path hostage. + event_sync::spawn_event_sync(app_handle.clone(), owner_keys); + if let Some(mgr) = huddle::models::global_model_manager() { mgr.start_stt_download(state.http_client.clone()); mgr.start_tts_download(state.http_client.clone());