asd
This commit is contained in:
@@ -95,29 +95,42 @@ Most scans become O(number of game dirs), with full recursion only when needed.
|
||||
- Any mismatch or missing delta falls back to `LibrarySnapshot`.
|
||||
- Loss of goodbye is harmless; stale timeout is authoritative.
|
||||
|
||||
## TODO: roadmap from current design to this one
|
||||
## Roadmap from current design to this one
|
||||
1. Protocol updates in `lanspread-proto`:
|
||||
- Add `Hello`, `HelloAck`, `LibrarySummary`, `LibrarySnapshot`,
|
||||
`LibraryDelta`, and optional `Goodbye`.
|
||||
- Add `peer_id`, `library_rev`, and `manifest_hash` to relevant types.
|
||||
- Define `Hello`, `HelloAck`, `LibrarySummary`, `LibrarySnapshot`,
|
||||
`LibraryDelta`, and optional `Goodbye` messages.
|
||||
- Thread `peer_id`, `library_rev`, and `manifest_hash` through all
|
||||
library and manifest-bearing types.
|
||||
- Make `HelloAck` carry the remote `library_rev` and `manifest_hash`
|
||||
so the client can immediately select `LibraryDelta` vs `LibrarySnapshot`.
|
||||
2. Peer identity:
|
||||
- Introduce stable `peer_id` in `PeerInfo` and `PeerGameDB`.
|
||||
- Map `peer_id` to current `SocketAddr` and update on IP changes.
|
||||
- Persist a stable `peer_id` (UUID) in the peer config and inject it into
|
||||
`PeerInfo` and `PeerGameDB` at startup.
|
||||
- Track `peer_id -> SocketAddr` in the discovery table and update the
|
||||
address on any incoming handshake or mDNS refresh.
|
||||
3. Discovery handshake:
|
||||
- Advertise TXT records in mDNS.
|
||||
- Add handshake in `run_peer_discovery` or connection setup.
|
||||
- Keep compatibility fallback to `ListGames` for older peers.
|
||||
- Publish `peer_id` and `library_rev` in mDNS TXT records to avoid
|
||||
immediate TCP/QUIC roundtrips when nothing changed.
|
||||
- Add a lightweight handshake in `run_peer_discovery` that exchanges
|
||||
`Hello`/`HelloAck` before any library sync.
|
||||
- Keep a fallback path that uses `ListGames` when `Hello` is unsupported.
|
||||
4. Library revisioning:
|
||||
- Track `library_rev` locally.
|
||||
- Apply `LibraryDelta` and reject stale revisions.
|
||||
- Use `LibrarySnapshot` for first sync or delta mismatch.
|
||||
- Store a monotonic `library_rev` locally and increment only after a
|
||||
successful index refresh completes.
|
||||
- Apply `LibraryDelta` when `library_rev` matches; reject stale or future
|
||||
revisions and request `LibrarySnapshot` instead.
|
||||
- Cache the last accepted `manifest_hash` per peer to short-circuit
|
||||
manifest requests when unchanged.
|
||||
5. Local index + scan optimizations:
|
||||
- Add cached index storage (e.g., `.lanspread/index.json`).
|
||||
- Implement filesystem watchers with debounce.
|
||||
- Add a low-frequency full scan as a safety net.
|
||||
- Introduce a cached index file (e.g., `.lanspread/index.json`) that stores
|
||||
per-root fingerprints and computed manifests.
|
||||
- Use filesystem watchers with a debounce window to collect changes and
|
||||
incrementally update the cache.
|
||||
- Schedule a low-frequency full scan to reconcile missed watcher events.
|
||||
6. Announce updates:
|
||||
- Replace broad `AnnounceGames` with deltas.
|
||||
- Send `LibrarySummary` on new connections.
|
||||
- Replace `AnnounceGames` with `LibraryDelta` broadcasts keyed by
|
||||
`library_rev`.
|
||||
- Send `LibrarySummary` on new connections to seed the delta flow.
|
||||
7. File manifest caching:
|
||||
- Store per-game `manifest_hash` and only fetch details when changed.
|
||||
8. Liveness:
|
||||
|
||||
@@ -11,10 +11,7 @@ use crate::{
|
||||
download::download_game_files,
|
||||
identity::FEATURE_LIBRARY_DELTA,
|
||||
local_games::{
|
||||
LocalLibraryScan,
|
||||
get_game_file_descriptions,
|
||||
local_download_available,
|
||||
scan_local_library,
|
||||
LocalLibraryScan, get_game_file_descriptions, local_download_available, scan_local_library,
|
||||
},
|
||||
network::{announce_games_to_peer, request_game_details_from_peer, send_library_delta},
|
||||
peer_db::{PeerGameDB, PeerId},
|
||||
@@ -218,10 +215,13 @@ pub async fn handle_download_game_files_command(
|
||||
return;
|
||||
}
|
||||
|
||||
let downloading = ctx.downloading_games.read().await;
|
||||
let local_dl_available = {
|
||||
let downloading = ctx.downloading_games.read().await;
|
||||
local_download_available(&games_folder, &id, &downloading).await
|
||||
};
|
||||
|
||||
if peer_whitelist.is_empty() {
|
||||
if local_download_available(&games_folder, &id, &downloading).await {
|
||||
drop(downloading);
|
||||
if local_dl_available {
|
||||
log::info!("Using locally downloaded files for game {id}; skipping peer transfer");
|
||||
if let Err(e) = tx_notify_ui.send(PeerEvent::DownloadGameFilesBegin { id: id.clone() })
|
||||
{
|
||||
@@ -237,7 +237,6 @@ pub async fn handle_download_game_files_command(
|
||||
}
|
||||
return;
|
||||
}
|
||||
drop(downloading);
|
||||
|
||||
{
|
||||
let mut in_progress = ctx.downloading_games.write().await;
|
||||
|
||||
Reference in New Issue
Block a user