fix(mesh): refresh federation chat names + roster after sync without restart (#42)
A peer accepted via invite is seeded into the mesh peer table with name=None, so it shows as "Archipelago <pubkey8>" in chat. Federation sync later learns the real name (update_node_state writes it to nodes.json) and discovers transitive peers (merge_transitive_peers), but nothing pushed those into the live mesh peer table — the chat list stayed stale until the next mesh restart, and transitive peers never appeared as contacts at all. Add RpcHandler::refresh_federation_mesh_peers() (re-runs the idempotent, onion-deduped seed_federation_peers_into_mesh) and call it after every periodic sync cycle (server.rs) and after the manual federation.sync-all RPC. Names now correct themselves and the full roster meshes within a sync cycle, no restart needed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
06cf80d4a2
commit
6de8173d18
@ -30,6 +30,25 @@ impl RpcHandler {
|
||||
mesh::upsert_federation_peer(&svc.shared_state(), pubkey_hex, did, name).await;
|
||||
}
|
||||
}
|
||||
|
||||
/// Re-seed every federation node from disk into the mesh peer table so the
|
||||
/// chat list reflects what the latest federation sync learned — display
|
||||
/// names (landed in `nodes.json` by `update_node_state` when a peer
|
||||
/// announces its name) and transitively-discovered peers (merged by
|
||||
/// `merge_transitive_peers`) — WITHOUT waiting for a mesh restart.
|
||||
///
|
||||
/// Without this, a peer accepted via invite (seeded with `name = None`)
|
||||
/// stays "Archipelago <pubkey8>" in chat until the next restart even after
|
||||
/// sync has learned its real name, and transitive peers never appear as
|
||||
/// chat contacts at all. `seed_federation_peers_into_mesh` is idempotent
|
||||
/// and dedups by onion, so calling it after each sync is safe.
|
||||
/// Best-effort: silently no-ops when mesh is off.
|
||||
pub(crate) async fn refresh_federation_mesh_peers(&self) {
|
||||
let svc = self.mesh_service.read().await;
|
||||
if let Some(svc) = svc.as_ref() {
|
||||
mesh::seed_federation_peers_into_mesh(&svc.shared_state(), &self.config.data_dir).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RpcHandler {
|
||||
@ -341,6 +360,10 @@ impl RpcHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// Push any names/roster the sync just learned into the live mesh peer
|
||||
// table so the chat list updates without a restart (#42).
|
||||
self.refresh_federation_mesh_peers().await;
|
||||
|
||||
Ok(serde_json::json!({
|
||||
"synced": synced,
|
||||
"failed": failed,
|
||||
|
||||
@ -508,6 +508,7 @@ impl Server {
|
||||
{
|
||||
let data_dir = config.data_dir.clone();
|
||||
let state = state_manager.clone();
|
||||
let rpc = api_handler.rpc_handler().clone();
|
||||
tokio::spawn(async move {
|
||||
// First run 60s after boot to let onboarding settle.
|
||||
tokio::time::sleep(Duration::from_secs(60)).await;
|
||||
@ -558,6 +559,10 @@ impl Server {
|
||||
}
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
}
|
||||
// After syncing every peer, push the names/roster just
|
||||
// learned (into nodes.json) into the live mesh peer table
|
||||
// so chat contacts refresh without a restart (#42).
|
||||
rpc.refresh_federation_mesh_peers().await;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user