perf(daemon): Arc<Names> + tokio RwLock, O(1) clone per IPC request

Was: Arc<std::sync::RwLock<Names>>; each dispatch clone_names() copied
4 HashMaps (~100KB for a user with 2700 contacts) and used std RwLock
which blocks the tokio worker thread during the clone.

Now: Arc<tokio::sync::RwLock<Arc<Names>>>; dispatch takes the read
guard, does Arc::clone (pointer bump), drops the guard, then spawns
the query work. Names is immutable after daemon startup; Arc is ideal.

Smoke tested: `wx sessions --json` returns correct data including
chat_type; 8 concurrent clients finish in 12ms.
This commit is contained in:
jackwener
2026-04-18 02:10:45 +08:00
parent e977007306
commit 1e52014a6b
2 changed files with 26 additions and 58 deletions
+4 -1
View File
@@ -75,7 +75,10 @@ async fn async_run() -> Result<()> {
let _ = db.get("session/session.db").await;
eprintln!("[daemon] 预热完成,联系人 {} 个", names.map.len());
let names_arc = Arc::new(std::sync::RwLock::new(names));
// 包一层内部 Arc:IPC 请求取 guard 后只做 Arc::clone(O(1)),
// 避免每次请求都全量 clone 几千个联系人的 HashMap。
// 用 tokio::sync::RwLock 允许 guard 跨 await(当前不跨,为未来 reload 留余地)。
let names_arc = Arc::new(tokio::sync::RwLock::new(Arc::new(names)));
// 启动 IPC server(阻塞)
server::serve(Arc::clone(&db), Arc::clone(&names_arc)).await?;