mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(desktop): plug memory leaks causing 37GB+ RAM growth (#223)
This commit is contained in:
@@ -32,7 +32,7 @@ const rules = [
|
||||
const overrides = new Map([
|
||||
["src-tauri/src/managed_agents/personas.rs", 600], // built-in persona system prompts (Solo, Ralph, Strategist) are long string literals
|
||||
["src-tauri/src/managed_agents/persona_card.rs", 772], // PNG/ZIP persona card codec + provider/model fields + 27 unit tests (~350 lines of tests); rustfmt adds line breaks around long literals/builders
|
||||
["src/app/AppShell.tsx", 840], // message edit state + handlers + ChannelPane edit prop threading + scrollback pagination + workflows view
|
||||
["src/app/AppShell.tsx", 860], // message edit state + handlers + ChannelPane edit prop threading + scrollback pagination + workflows view + memory-leak safeguards
|
||||
["src/features/channels/hooks.ts", 550], // canvas query + mutation hooks + DM hide mutation
|
||||
["src/features/channels/ui/ChannelManagementSheet.tsx", 800],
|
||||
["src/features/messages/hooks.ts", 500], // message query/mutation hooks + optimistic updates
|
||||
|
||||
@@ -483,6 +483,21 @@ export function AppShell() {
|
||||
requestedAncestorIdsRef.current.add(eventId);
|
||||
}
|
||||
|
||||
// Prevent unbounded growth — evict oldest entries when the set exceeds
|
||||
// a reasonable size. Since Set iteration is insertion-ordered we drop
|
||||
// the first (oldest) entries.
|
||||
const MAX_REQUESTED_ANCESTORS = 500;
|
||||
if (requestedAncestorIdsRef.current.size > MAX_REQUESTED_ANCESTORS) {
|
||||
const excess =
|
||||
requestedAncestorIdsRef.current.size - MAX_REQUESTED_ANCESTORS;
|
||||
let removed = 0;
|
||||
for (const id of requestedAncestorIdsRef.current) {
|
||||
if (removed >= excess) break;
|
||||
requestedAncestorIdsRef.current.delete(id);
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
|
||||
let isCancelled = false;
|
||||
|
||||
void Promise.all(
|
||||
|
||||
@@ -140,7 +140,7 @@ export function useChannelMessagesQuery(channel: Channel | null) {
|
||||
return mergedHistory;
|
||||
},
|
||||
staleTime: Number.POSITIVE_INFINITY,
|
||||
gcTime: 30 * 60 * 1_000,
|
||||
gcTime: 5 * 60 * 1_000,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -373,6 +373,19 @@ export function useFeedDesktopNotifications(
|
||||
for (const item of currentFeedItems) {
|
||||
nextSeenItemIds.add(item.id);
|
||||
}
|
||||
|
||||
// Prevent unbounded growth — keep only the most recent entries.
|
||||
const MAX_SEEN_FEED_ITEMS = 500;
|
||||
if (nextSeenItemIds.size > MAX_SEEN_FEED_ITEMS) {
|
||||
const excess = nextSeenItemIds.size - MAX_SEEN_FEED_ITEMS;
|
||||
let removed = 0;
|
||||
for (const id of nextSeenItemIds) {
|
||||
if (removed >= excess) break;
|
||||
nextSeenItemIds.delete(id);
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
|
||||
seenItemIdsRef.current = nextSeenItemIds;
|
||||
|
||||
for (const item of newItems) {
|
||||
|
||||
@@ -14,6 +14,7 @@ const queryClient = new QueryClient({
|
||||
retry: 1,
|
||||
refetchOnWindowFocus: false,
|
||||
networkMode: "always",
|
||||
gcTime: 5 * 60 * 1_000,
|
||||
},
|
||||
mutations: {
|
||||
networkMode: "always",
|
||||
|
||||
@@ -44,6 +44,7 @@ export class RelayClient {
|
||||
private reconnectListeners = new Set<() => void>();
|
||||
private hasConnectedOnce = false;
|
||||
private notifyReconnectListeners = false;
|
||||
private onMessageChannel: Channel<unknown> | null = null;
|
||||
|
||||
async fetchChannelHistory(channelId: string, limit = 50) {
|
||||
return this.fetchHistory(this.buildChannelFilter(channelId, limit));
|
||||
@@ -217,13 +218,13 @@ export class RelayClient {
|
||||
this.relayUrl = await getRelayWsUrl();
|
||||
}
|
||||
|
||||
const onMessageChannel = new Channel<unknown>((message) => {
|
||||
this.onMessageChannel = new Channel<unknown>((message) => {
|
||||
void this.handleWsMessage(message);
|
||||
});
|
||||
|
||||
this.wsId = await invoke<number>("plugin:websocket|connect", {
|
||||
url: this.relayUrl,
|
||||
onMessage: onMessageChannel,
|
||||
onMessage: this.onMessageChannel,
|
||||
config: {},
|
||||
});
|
||||
|
||||
@@ -700,6 +701,7 @@ export class RelayClient {
|
||||
reconnect?: boolean;
|
||||
},
|
||||
) {
|
||||
this.onMessageChannel = null;
|
||||
if (this.flushTimeout !== null) window.clearTimeout(this.flushTimeout);
|
||||
this.flushTimeout = null;
|
||||
this.eventBuffer = [];
|
||||
|
||||
Reference in New Issue
Block a user