fix(core): serialize provision runs with a per-VM lock - #34
Conversation
Two concurrent Apply runs against one VM each start apk, and the second hits apk's own database lock and fails with exit 99. Apply now holds an exclusive flock on <VM dir>/provision.lock for the whole run and returns ErrProvisionInProgress when another run already holds it.
core.Apply's ErrProvisionInProgress means another run already holds the VM's lock, not that this run did anything wrong. The CLI's apply, provision, and up commands print a short notice and exit 0; the TUI shows a toast instead of the red error path. runProvision drives sshx.Provision directly rather than through Apply, so it takes core.WithProvisionLock itself around that call.
|
Warning Review limit reached
Next review available in: 57 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Two provision runs against one VM each start
apk, and the second dies on the apk database lock with exit 99:Unable to lock database: Resource temporarily unavailable. The TUI guarded against itself in one process, but a CLIstoat upauto-provision, a manualstoat provision, and the TUI did not share that guard.core.WithProvisionLock(dir, fn)holds an exclusive non-blockingflockon<vm dir>/provision.lockwhilefnruns. A second run finds the lock held and returnsErrProvisionInProgresswithout touching the guest. The flock is advisory and released by the kernel on process death, so a lock file left by a crash never blocks the next run.Every provision path funnels through it:
core.Applywraps its body in the lock (used by the TUI,stoat up,stoat apply).stoat provisiondrivessshx.Provisiondirectly, so it takes the lock itself around that call.A concurrent run is a skip, not an error: the CLI prints ": provision already running" and exits 0 (JSON gets a
skipped_reason); the TUI shows a plain toast. The in-processm.provisioningguard stays as the same-process fast path.Tests:
WithProvisionLockserializes and reacquires after release;ApplyreturnsErrProvisionInProgresswhen the lock is held, before it reaches ssh.just checkandjust testpass.