40697a73e5
NEXT_STEPS item 1 called out that streamed install was still CLI-only because the Tauri app started the peer with no stream provider. Users can now choose an explicit "Low disk install" action from the game detail modal for remote-only games instead of taking the default archive-preserving download path. The GUI command queues a normal peer detail fetch first so the peer database has the file metadata needed for source validation. A small pending handoff in Tauri routes the resulting GotGameFiles event into StreamInstallGame instead of DownloadGameFiles, and clears that pending state on no-peer or download failure events. This keeps the existing download continuation untouched for the default action. The external unrar stream provider moved from the CLI harness into lanspread-peer so CLI and Tauri use the same implementation. Tauri resolves the bundled unrar sidecar path and injects that provider at peer startup; falling back to the noop provider keeps peer startup alive if the sidecar cannot be resolved, while the streamed install operation still fails safely. Test Plan: - just fmt - just test - just frontend-test - just clippy - just build - git diff --check Refs: NEXT_STEPS.md item 1
67 lines
2.5 KiB
Markdown
67 lines
2.5 KiB
Markdown
# Streamed Install Next Steps
|
||
|
||
I’d treat the prototype as proof of the hard part: “can we stream
|
||
archive-derived install bytes into `local/` without making the receiver a
|
||
source?” Yes. Next I’d harden the pieces that decide whether this is
|
||
product-ready.
|
||
|
||
1. **Done — Move from CLI-only to real app integration**
|
||
|
||
The GUI now has an explicit “Low disk install” action in the game detail
|
||
modal for remote-only games. The Tauri backend queues that path through
|
||
`stream_install_game`, injects the shared external `unrar` stream provider,
|
||
and hands fetched file details to `StreamInstallGame` instead of the normal
|
||
download command.
|
||
|
||
2. **Replace per-file `unrar p` with a final archive provider**
|
||
|
||
The prototype provider is intentionally simple: `unrar lt`, then `unrar p`
|
||
per file. Good for non-solid archives, bad for solid archives. Final shape
|
||
should be a one-pass provider with real entry boundaries, likely via libunrar
|
||
or a purpose-built wrapper.
|
||
|
||
3. **Handle solid archives deliberately**
|
||
|
||
Add archive inspection that decides:
|
||
|
||
- non-solid: per-file streaming is fine
|
||
- solid: one sequential archive pass only
|
||
|
||
This is the big architectural fork we discussed, and the prototype’s
|
||
provider is the thing to swap.
|
||
|
||
4. **Decide the integrity model**
|
||
|
||
Current prototype verifies streamed bytes against RAR CRC32 from the
|
||
sender’s archive headers. That catches corruption and provider bugs. It does
|
||
not protect against a malicious peer lying. If you care about that, the next
|
||
step is catalog-side trusted hashes for archive or extracted files.
|
||
|
||
5. **Upgrade retry/resume semantics**
|
||
|
||
Right now, failed stream means failed operation and rollback. Next useful
|
||
step:
|
||
|
||
- retry whole stream from another trusted peer
|
||
- later, maybe keep completed files and restart only the interrupted file
|
||
- avoid byte-offset resume until there’s a strong reason
|
||
|
||
6. **Expand scenario coverage**
|
||
|
||
I’d add cases for:
|
||
|
||
- sender disconnect mid-stream
|
||
- receiver cancel mid-stream
|
||
- corrupted/truncated stream fails and leaves no `local/`
|
||
- already-installed game rejects streamed install
|
||
- multi-archive `.eti` roots stream in sorted order
|
||
|
||
7. **Clean product semantics**
|
||
|
||
Decide how the UI labels this state. It is installed but not downloaded, so
|
||
“Local only” is technically correct, but users may need a clear affordance
|
||
like “Installed, not shareable”.
|
||
|
||
My recommended next slice: make the provider abstraction final-ish, then
|
||
implement a real one-pass provider. Everything else builds cleanly on that.
|