mirror of
https://github.com/MobAI-App/simslim.git
synced 2026-10-02 19:57:23 +02:00
Four defects found reviewing the previous commit. **Batch completion could erase a newer reservation.** `slim` and `restore` cleared their own reservation in a `defer`, and `runConcurrently` cleared it again when the result arrived. Those run in different MainActor tasks, so another operation could claim the device in the gap and have its reservation wiped by the batch's stale clear — leaving the device shown as free while work ran on it. The runner is now the sole owner. **Overlapping operations could lose their final refresh.** `refresh()` dropped any request made while one was in flight. That was safe when every mutation was globally exclusive; now that two devices finish independently, the second one's refresh could be dropped after the first had already read the device list, and its row would stay stale indefinitely. Requests made during a refresh are coalesced into a follow-up run, mirroring `diskReloadRequested`. **Batch controls were enabled but silently did nothing.** Relaxing the view gating left `runBatch`, `cleanDisk`, `analyzeDisk` and `runManagementBatch` guarding on `batchProgress == nil`, so Slim/Unslim/Erase/Delete/Clean on an idle device during a batch returned without doing anything. They now gate on `canStartBatchOnSelection` / `isBatchRunning`; per-device actions (boot, shutdown, clone, rename, measure) stay live as intended. **`ensure` read a booted device without waiting for boot.** `simctl list` reports Booted from the moment a boot starts, so `readDisabled` on a device that is still coming up would fail the whole command instead of waiting. The booted branch calls `BootAndWait` first; on a device that really is booted that costs ~0.2s. Also assert full transition coverage in the applyDelta concurrency test — it pinned the bound but would have passed an implementation that ran only the first `spawnWorkers` labels.