Fix storage lock contention: reduce lock holds across 6 hot paths
- get_blob_for_post: 3 sequential locks → 1 combined acquisition - prefetch_blobs_from_peer: lock only for DB reads, blob checks outside lock - fetch_engagement_from_peer: explicit lock release before next network I/O - serve_post: 4 locks (2 redundant) → 2 - run_replication_check: 2 locks → 1 combined - Badge cycle: N+2 IPC calls → 1 (new get_badge_counts command) - Follow timeout: 15s cap on auto-sync-on-follow to prevent UI hang - Notification clearing: clear system notifications on conversation read Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3cc39590a7
commit
89d6a853f5
5 changed files with 152 additions and 106 deletions
|
|
@ -124,8 +124,8 @@ async fn serve_post(stream: &mut TcpStream, path: &str, node: &Arc<Node>, browse
|
|||
None
|
||||
};
|
||||
|
||||
// Gather all known holders: author + CDN downstream peers
|
||||
let (holders, local_post) = {
|
||||
// Single lock: gather holders, local post, AND author name if local
|
||||
let (holders, local_post, local_author_name) = {
|
||||
let store = node.storage.lock().await;
|
||||
|
||||
let mut holders = Vec::new();
|
||||
|
|
@ -141,7 +141,18 @@ async fn serve_post(stream: &mut TcpStream, path: &str, node: &Arc<Node>, browse
|
|||
}
|
||||
|
||||
let local = store.get_post_with_visibility(&post_id).ok().flatten();
|
||||
(holders, local)
|
||||
// If we have the post locally and it's public, get author name now
|
||||
let author_name = if let Some((ref post, ref vis)) = local {
|
||||
if matches!(vis, PostVisibility::Public) {
|
||||
store.get_profile(&post.author).ok().flatten()
|
||||
.map(|p| p.display_name).unwrap_or_default()
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
(holders, local, author_name)
|
||||
};
|
||||
|
||||
// --- Tier 1 & 2: Try direct redirect to an HTTP-capable holder ---
|
||||
|
|
@ -157,15 +168,10 @@ async fn serve_post(stream: &mut TcpStream, path: &str, node: &Arc<Node>, browse
|
|||
|
||||
// --- Tier 3: QUIC proxy fallback ---
|
||||
|
||||
// Check local storage first
|
||||
// Check local storage first (author_name already fetched above)
|
||||
if let Some((post, visibility)) = local_post {
|
||||
if matches!(visibility, PostVisibility::Public) {
|
||||
let author_name = {
|
||||
let store = node.storage.lock().await;
|
||||
store.get_profile(&post.author).ok().flatten()
|
||||
.map(|p| p.display_name).unwrap_or_default()
|
||||
};
|
||||
let html = render_post_html(&post, &post_id, &author_name);
|
||||
let html = render_post_html(&post, &post_id, &local_author_name);
|
||||
let _ = write_http_response(stream, 200, "text/html; charset=utf-8", html.as_bytes()).await;
|
||||
return;
|
||||
}
|
||||
|
|
@ -182,14 +188,12 @@ async fn serve_post(stream: &mut TcpStream, path: &str, node: &Arc<Node>, browse
|
|||
|
||||
match search_result {
|
||||
Ok(Ok(Some(sync_post))) => {
|
||||
{
|
||||
// Single lock: store post AND get author name
|
||||
let author_name = {
|
||||
let store = node.storage.lock().await;
|
||||
let _ = store.store_post_with_visibility(
|
||||
&sync_post.id, &sync_post.post, &sync_post.visibility,
|
||||
);
|
||||
}
|
||||
let author_name = {
|
||||
let store = node.storage.lock().await;
|
||||
store.get_profile(&sync_post.post.author).ok().flatten()
|
||||
.map(|p| p.display_name).unwrap_or_default()
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue