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:
Scott Reimers 2026-03-21 13:02:30 -04:00
parent 3cc39590a7
commit 89d6a853f5
5 changed files with 152 additions and 106 deletions

View file

@ -3007,33 +3007,12 @@ async function init() {
updateNetworkIndicator();
}, 10000);
// Badge updates for non-active tabs — every 30 seconds (lightweight)
// Badge updates for non-active tabs — every 30 seconds (single IPC call)
setInterval(async () => {
try {
// Feed badge
if (currentTab !== 'feed' && _lastFeedViewMs > 0) {
const allPosts = await invoke('get_feed');
const isDM = p => p.intentKind === 'direct' || (p.intentKind === 'unknown' && (p.visibility === 'encrypted-for-me' || (p.isMe && p.recipients && p.recipients.length > 0)));
const newCount = allPosts.filter(p => !isDM(p) && !p.isMe && p.timestampMs > _lastFeedViewMs).length;
updateTabBadge('feed', newCount);
}
// My Posts badge (new engagement)
if (currentTab !== 'myposts') {
const posts = await invoke('get_all_posts');
const mine = posts.filter(p => p.isMe && p.intentKind !== 'direct' && !(p.intentKind === 'unknown' && p.recipients && p.recipients.length > 0));
let newEngagement = 0;
for (const p of mine) {
const totalReacts = (p.reactionCounts || []).reduce((sum, r) => sum + r.count, 0);
const totalComments = p.commentCount || 0;
if (totalReacts > 0 || totalComments > 0) {
try {
const seen = await invoke('get_seen_engagement', { postId: p.id });
if (totalReacts > (seen.seenReactCount || 0) || totalComments > (seen.seenCommentCount || 0)) newEngagement++;
} catch (_) { newEngagement++; }
}
}
updateTabBadge('myposts', newEngagement);
}
const badges = await invoke('get_badge_counts', { lastFeedViewMs: _lastFeedViewMs });
if (currentTab !== 'feed') updateTabBadge('feed', badges.newFeed);
if (currentTab !== 'myposts') updateTabBadge('myposts', badges.newEngagement);
} catch (_) {}
}, 30000);