ChatGPT Codex 5.5 xhigh refactored even more

This commit is contained in:
2026-05-02 15:31:37 +02:00
parent 86d0f93ede
commit b4585b663a
24 changed files with 2160 additions and 1972 deletions
@@ -0,0 +1,267 @@
//! Protocol handshakes and library synchronization between peers.
use std::{net::SocketAddr, sync::Arc};
use lanspread_proto::{Hello, HelloAck, LibraryDelta, LibrarySnapshot, PROTOCOL_VERSION};
use tokio::sync::{RwLock, mpsc::UnboundedSender};
use crate::{
PeerEvent,
context::PeerCtx,
events,
identity::default_features,
library::{LocalLibraryState, build_library_snapshot, build_library_summary},
network::{exchange_hello, send_library_delta, send_library_snapshot, send_library_summary},
peer_db::{PeerGameDB, PeerId, PeerUpsert},
};
enum LibraryUpdate {
Delta(LibraryDelta),
Snapshot(LibrarySnapshot),
}
pub(super) async fn build_hello_ack(ctx: &PeerCtx) -> HelloAck {
let library_guard = ctx.local_library.read().await;
HelloAck {
peer_id: ctx.peer_id.as_ref().clone(),
proto_ver: PROTOCOL_VERSION,
library_rev: library_guard.revision,
library_digest: library_guard.digest,
features: default_features(),
}
}
async fn build_hello_from_state(
peer_id: &str,
local_library: &Arc<RwLock<LocalLibraryState>>,
) -> Hello {
let library_guard = local_library.read().await;
Hello {
peer_id: peer_id.to_string(),
proto_ver: PROTOCOL_VERSION,
library_rev: library_guard.revision,
library_digest: library_guard.digest,
features: default_features(),
}
}
pub(super) async fn perform_handshake_with_peer(
peer_id: Arc<String>,
local_library: Arc<RwLock<LocalLibraryState>>,
peer_game_db: Arc<RwLock<PeerGameDB>>,
tx_notify_ui: UnboundedSender<PeerEvent>,
peer_addr: SocketAddr,
peer_id_hint: Option<PeerId>,
) -> eyre::Result<()> {
let hello = build_hello_from_state(peer_id.as_ref(), &local_library).await;
let ack = exchange_hello(peer_addr, hello).await?;
if ack.proto_ver != PROTOCOL_VERSION {
log::warn!(
"Peer {peer_addr} uses incompatible protocol {} (expected {PROTOCOL_VERSION})",
ack.proto_ver
);
return Ok(());
}
if ack.peer_id == *peer_id {
log::trace!("Ignoring handshake with self for {peer_addr}");
return Ok(());
}
if let Some(expected) = peer_id_hint.as_ref()
&& expected != &ack.peer_id
{
log::warn!(
"Peer {peer_addr} id mismatch: mDNS advertised {expected}, hello ack returned {}",
ack.peer_id
);
let _ = peer_game_db.write().await.remove_peer(expected);
}
let upsert = record_remote_library(
&peer_game_db,
ack.peer_id.clone(),
peer_addr,
ack.library_rev,
ack.library_digest,
ack.features.clone(),
)
.await;
after_peer_library_recorded(
upsert,
peer_addr,
ack.library_rev,
ack.library_digest,
&local_library,
&peer_game_db,
&tx_notify_ui,
)
.await;
Ok(())
}
pub(super) async fn accept_inbound_hello(
ctx: &PeerCtx,
remote_addr: Option<SocketAddr>,
hello: Hello,
) -> HelloAck {
if hello.peer_id == *ctx.peer_id {
log::trace!("Ignoring hello from self");
return build_hello_ack(ctx).await;
}
if hello.proto_ver != PROTOCOL_VERSION {
log::warn!(
"Incompatible protocol from {remote_addr:?}: {}",
hello.proto_ver
);
return build_hello_ack(ctx).await;
}
if let Some(addr) = remote_addr {
let upsert = record_remote_library(
&ctx.peer_game_db,
hello.peer_id.clone(),
addr,
hello.library_rev,
hello.library_digest,
hello.features.clone(),
)
.await;
after_peer_library_recorded(
upsert,
addr,
hello.library_rev,
hello.library_digest,
&ctx.local_library,
&ctx.peer_game_db,
&ctx.tx_notify_ui,
)
.await;
}
build_hello_ack(ctx).await
}
pub(super) fn spawn_library_resync(
peer_id: Arc<String>,
local_library: Arc<RwLock<LocalLibraryState>>,
peer_game_db: Arc<RwLock<PeerGameDB>>,
tx_notify_ui: UnboundedSender<PeerEvent>,
peer_addr: SocketAddr,
peer_id_hint: PeerId,
reason: &'static str,
) {
tokio::spawn(async move {
if let Err(err) = perform_handshake_with_peer(
peer_id,
local_library,
peer_game_db,
tx_notify_ui,
peer_addr,
Some(peer_id_hint),
)
.await
{
log::warn!("Failed to {reason} library from {peer_addr}: {err}");
}
});
}
async fn record_remote_library(
peer_game_db: &Arc<RwLock<PeerGameDB>>,
peer_id: PeerId,
peer_addr: SocketAddr,
library_rev: u64,
library_digest: u64,
features: Vec<String>,
) -> PeerUpsert {
let mut db = peer_game_db.write().await;
let upsert = db.upsert_peer(peer_id.clone(), peer_addr);
db.update_peer_library(&peer_id, library_rev, library_digest, features);
upsert
}
async fn after_peer_library_recorded(
upsert: PeerUpsert,
peer_addr: SocketAddr,
remote_library_rev: u64,
remote_library_digest: u64,
local_library: &Arc<RwLock<LocalLibraryState>>,
peer_game_db: &Arc<RwLock<PeerGameDB>>,
tx_notify_ui: &UnboundedSender<PeerEvent>,
) {
if upsert.is_new {
events::emit_peer_discovered(peer_game_db, tx_notify_ui, peer_addr).await;
send_local_library_summary(peer_addr, local_library).await;
}
send_local_library_update_if_needed(
peer_addr,
local_library,
remote_library_rev,
remote_library_digest,
)
.await;
}
async fn send_local_library_summary(
peer_addr: SocketAddr,
local_library: &Arc<RwLock<LocalLibraryState>>,
) {
let summary = {
let library_guard = local_library.read().await;
build_library_summary(&library_guard)
};
tokio::spawn(async move {
if let Err(err) = send_library_summary(peer_addr, summary).await {
log::warn!("Failed to send library summary to {peer_addr}: {err}");
}
});
}
async fn send_local_library_update_if_needed(
peer_addr: SocketAddr,
local_library: &Arc<RwLock<LocalLibraryState>>,
remote_rev: u64,
remote_digest: u64,
) {
if let Some(update) = select_library_update(local_library, remote_rev, remote_digest).await {
tokio::spawn(async move {
let result = match update {
LibraryUpdate::Delta(delta) => send_library_delta(peer_addr, delta).await,
LibraryUpdate::Snapshot(snapshot) => {
send_library_snapshot(peer_addr, snapshot).await
}
};
if let Err(err) = result {
log::warn!("Failed to send library update to {peer_addr}: {err}");
}
});
}
}
async fn select_library_update(
local_library: &Arc<RwLock<LocalLibraryState>>,
remote_rev: u64,
remote_digest: u64,
) -> Option<LibraryUpdate> {
let library_guard = local_library.read().await;
if library_guard.digest == remote_digest || remote_rev > library_guard.revision {
return None;
}
if let Some(delta) = library_guard.delta_since(remote_rev) {
return Some(LibraryUpdate::Delta(delta));
}
Some(LibraryUpdate::Snapshot(build_library_snapshot(
&library_guard,
)))
}