Files
lanspread/IMPL_DECISIONS.md
T
ddidderr b5d20c1e72 fix(peer): refresh settled install state after operations
The follow-up review found a few stale lifecycle edges around local game
transactions. Recovery could sweep active roots, post-operation refreshes
still re-ran full startup recovery, and the UI kept inferring local-only state
from downloaded and installed flags instead of the backend availability.

This updates the peer lifecycle so startup recovery skips active operations,
install/update/uninstall refresh only the affected game after the operation
guard is dropped, and path-changing game-directory updates are rejected while
operations are active. It also removes the dead UpdateGame command, drops the
unused manifest_hash write field while preserving old JSON reads, renames the
internal install-finished event, and carries availability through the DB,
peer summaries, Tauri refreshes, and the React model.

The included follow-up documents record the review source, implementation
decisions, and the remaining FOLLOW_UP_2.md work so later commits can stay
small instead of reopening the completed plan items.

Test Plan:
- git diff --check
- just fmt
- just clippy
- just test

Follow-up-Plan: FOLLOW_UP_PLAN.md
2026-05-16 08:50:51 +02:00

2.0 KiB

Implementation Decisions

  • Added a just test recipe so unit tests can be run through the repository's required just ... command surface instead of invoking cargo test directly.
  • Renamed the frontend success event to game-install-finished; the old unpack name no longer matched the transactional install/update lifecycle.
  • Implemented watcher rescans by reusing the existing .lanspread/library_index.json cache and updating a single game entry in that index. This satisfies the per-ID optimized rescan requirement without adding a second cache format.
  • Split full startup recovery from ordinary settled refreshes. Startup and real SetGameDir changes run recovery plus a scan; install/update/uninstall completion only rescans the affected game after operation tracking has been cleared.
  • Rejected path-changing SetGameDir while operations are active. Same-path refreshes are allowed and deliberately skip full recovery so they cannot sweep download transients for in-flight work.
  • Kept a separate active_downloads cancellation-token map next to the single active_operations table. The operation table is the authoritative state for gates; the token map is only cancellation plumbing for in-flight downloads.
  • Treated a downloaded-but-not-installed game as immediately installable from Tauri by sending PeerCommand::InstallGame directly. A not-downloaded game still uses GetGame, and the peer auto-installs after the sentinel commit.
  • Removed the dead internal PeerCommand::UpdateGame path. The UI update button intentionally sends GetGame, and the peer infers install versus update from the presence of local/ after archives are available.
  • Kept Availability::Downloading in the wire protocol for compatibility, but local summaries do not emit it today because active operations are gated out of scans and serving decisions.
  • Threaded availability through the UI-facing Game payload so LocalOnly rendering follows backend state instead of reverse-engineering it from installed && !downloaded.