resync_workspaces

Function resync_workspaces 

Source
async fn resync_workspaces(
    state: &Arc<Mutex<State>>,
    wstore: &WaveStore,
) -> Result<(), Box<dyn Error>>
Expand description

Snapshot state.workspaces and reconcile against SQLite — INSERT/UPDATE only, no deletes. Workspace-scoped (tab/block resync expands here as each entity’s RPC layer migrates).

Why no delete-phase: during the migration window, workspaces can be created OUTSIDE the reducer (e.g., the still-wcore-direct CreateWindow flow calls wcore::create_window_full which creates a workspace under the hood). Those workspaces aren’t in state.workspaces. If the subscriber lagged and we did a delete-not-in-snapshot pass, we’d cascade-delete legitimate workspaces — data loss triggered by bus pressure rather than a user action. Far better for a stale workspace deleted-via-reducer to linger on disk after a Lagged event than to lose a real one. (codex P1 #615.)

Stale-after-Lagged scenario: reducer fires WorkspaceDeleted, the subscriber drops it on Lagged, resync runs but only insert/updates. SQLite still has the deleted workspace’s row. The next user-driven DeleteWorkspace (which falls through to wcore::delete_workspace for unknown-to-reducer rows) cleans it up. Acceptable behaviour during the migration; tightens once all RPC is reducer-driven.

Strategy:

  1. Lock state, snapshot the workspace map (ids + names), release the lock.
  2. For each workspace in the snapshot: insert if missing, no-op if name matches, update if name differs.