Skip to content

fix: first-run wizard reappears after setup (configured latch + serialized settings writes)#38

Merged
Soulhackzlol merged 1 commit into
mainfrom
fix/configured-wizard-latch
Jul 6, 2026
Merged

fix: first-run wizard reappears after setup (configured latch + serialized settings writes)#38
Soulhackzlol merged 1 commit into
mainfrom
fix/configured-wizard-latch

Conversation

@Soulhackzlol

Copy link
Copy Markdown
Owner

Summary

The first-run wizard could reappear after setup was already complete. Reported by fashionxd. Two independent root causes, both fixed:

  1. Semantic (the reproducible one). configured was recomputed live on every destination toggle/delete as "is any destination streamable right now." So disabling or deleting your last enabled + well-formed destination flipped configured=false and reopened the wizard on next load. The 0.1.10 dock's one-tap destination toggle made this easy to hit for single-destination users. It is now a one-way first-run latch, cleared only by an explicit full reset (scope=all). The "ready to stream" condition is extracted into a tested has_streamable_dest.

  2. Race (secondary). Every settings handler did an unsynchronized settings.borrow().clone() -> mutate -> send(whole_struct), one task per connection. Two overlapping POSTs lost one update, which could resurrect a stale configured=false. All 12 settings mutators now serialize through a single process-wide SETTINGS_WRITE_LOCK (a std::sync::Mutex; the critical section never .awaits, and its !Send guard makes that a compile-time guarantee). This closes the lost-update race for every settings field, not just this flag.

Behavior change

Removing/disabling your last destination now leaves you on the dashboard (empty Destinations state) instead of reopening the wizard. "Reset everything" still returns to the wizard.

Verification

  • cargo fmt, cargo clippy --release clean, cargo test --release 238 passed (+2 regression tests pinning the latch contract).
  • Working tree was byte-identical to the released v0.1.10, so no integration drift.

…ites

The first-run wizard could reappear after setup was already done. Two
independent causes, both fixed here:

- `configured` was recomputed live on every destination toggle/delete, so
  disabling or deleting the last enabled + well-formed destination flipped it
  back to false and reopened the wizard. It is now a one-way first-run latch,
  cleared only by an explicit full reset. Extracted the "ready to stream"
  condition into a tested `has_streamable_dest`.
- Every settings handler did an unsynchronized clone -> mutate -> send() of
  the whole Settings struct, so two overlapping POSTs lost one update (which
  could resurrect a stale configured=false). All settings mutations now
  serialize through one process-wide write lock (SETTINGS_WRITE_LOCK).

Adds latch + streamable-dest regression tests (238 passing). README test
count refreshed. Reported by fashionxd.
@Soulhackzlol Soulhackzlol self-assigned this Jul 6, 2026
@Soulhackzlol Soulhackzlol added the bug Something isn't working label Jul 6, 2026
@Soulhackzlol
Soulhackzlol merged commit f3f13ad into main Jul 6, 2026
4 checks passed
@Soulhackzlol
Soulhackzlol deleted the fix/configured-wizard-latch branch July 6, 2026 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant