mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
perf(app): cut idle renderer CPU and unbounded memory growth (#1724)
This commit is contained in:
1 parent
b4a5eb77a8
commit
5660972c71
13 files changed
+453
-345
No files matched your search
@@ -39,6 +39,7 @@ type Listener = () => void;
|
||||
|
||||
const EMPTY_REACTIONS: ReadonlyArray<MessageReaction> = Object.freeze([]);
|
||||
const EMPTY_USERS: ReadonlyArray<User> = Object.freeze([]);
|
||||
const MAX_TRACKED_REACTION_REQUEST_KEYS = 512;
|
||||
const createEmptyReactorEntry = (requestSerial = 0): ReactorEntry => ({
|
||||
snapshot: createReactionUsersSnapshot(requestSerial),
|
||||
});
|
||||
@@ -68,6 +69,7 @@ export class MessageReactionsManager {
|
||||
private reactors: Map<string, ReactorEntry> = new Map();
|
||||
private _keysByMessage: Map<string, Set<string>> = new Map();
|
||||
private retiredReactionRequests: Map<string, number> = new Map();
|
||||
private inFlightReactionRequests: Map<string, Set<number>> = new Map();
|
||||
private messageListeners: Map<string, Set<Listener>> = new Map();
|
||||
private reactionListeners: Map<string, Set<Listener>> = new Map();
|
||||
private transactionDepth = 0;
|
||||
@@ -247,7 +249,9 @@ export class MessageReactionsManager {
|
||||
handleFetchPending(messageId: string, emoji: ReactionEmoji): number {
|
||||
const entry = this.getOrCreateReactorEntry(messageId, emoji);
|
||||
this.commitReactorEvent(messageId, emoji, entry, {type: 'fetch.pending'});
|
||||
return entry.snapshot.context.activeRequestId ?? entry.snapshot.context.requestSerial;
|
||||
const requestId = entry.snapshot.context.activeRequestId ?? entry.snapshot.context.requestSerial;
|
||||
this.trackInFlightRequest(getReactionKey(messageId, emoji), requestId);
|
||||
return requestId;
|
||||
}
|
||||
|
||||
handleFetchSuccess(
|
||||
@@ -261,7 +265,9 @@ export class MessageReactionsManager {
|
||||
nextAfter?: string | null,
|
||||
): void {
|
||||
const key = getReactionKey(messageId, emoji);
|
||||
if (this.shouldIgnoreFetchResult(key, requestId)) return;
|
||||
const ignored = this.shouldIgnoreFetchResult(key, requestId);
|
||||
this.settleInFlightRequest(key, requestId);
|
||||
if (ignored) return;
|
||||
const entry = this.getOrCreateReactorEntry(messageId, emoji);
|
||||
Users.cacheUsers(users.slice());
|
||||
this.commitReactorEvent(messageId, emoji, entry, {
|
||||
@@ -288,7 +294,9 @@ export class MessageReactionsManager {
|
||||
nextAfter?: string | null,
|
||||
): void {
|
||||
const key = getReactionKey(messageId, emoji);
|
||||
if (this.shouldIgnoreFetchResult(key, requestId)) return;
|
||||
const ignored = this.shouldIgnoreFetchResult(key, requestId);
|
||||
this.settleInFlightRequest(key, requestId);
|
||||
if (ignored) return;
|
||||
const entry = this.getOrCreateReactorEntry(messageId, emoji);
|
||||
Users.cacheUsers(users.slice());
|
||||
this.commitReactorEvent(messageId, emoji, entry, {
|
||||
@@ -306,7 +314,9 @@ export class MessageReactionsManager {
|
||||
|
||||
handleFetchError(messageId: string, emoji: ReactionEmoji, requestId?: number): void {
|
||||
const key = getReactionKey(messageId, emoji);
|
||||
if (this.shouldIgnoreFetchResult(key, requestId)) return;
|
||||
const ignored = this.shouldIgnoreFetchResult(key, requestId);
|
||||
this.settleInFlightRequest(key, requestId);
|
||||
if (ignored) return;
|
||||
this.commitReactorEvent(messageId, emoji, this.getOrCreateReactorEntry(messageId, emoji), {
|
||||
type: 'fetch.error',
|
||||
requestId,
|
||||
@@ -370,10 +380,37 @@ export class MessageReactionsManager {
|
||||
}
|
||||
|
||||
private retireReactionEntry(key: string, entry = this.reactors.get(key)): void {
|
||||
this.reactors.delete(key);
|
||||
if (!this.inFlightReactionRequests.has(key)) {
|
||||
this.retiredReactionRequests.delete(key);
|
||||
return;
|
||||
}
|
||||
const requestSerial = entry?.snapshot.context.requestSerial ?? 0;
|
||||
const nextRequestId = Math.max(this.retiredReactionRequests.get(key) ?? 0, requestSerial);
|
||||
this.retiredReactionRequests.set(key, nextRequestId);
|
||||
this.reactors.delete(key);
|
||||
}
|
||||
|
||||
private trackInFlightRequest(key: string, requestId: number): void {
|
||||
const requestIds = this.inFlightReactionRequests.get(key) ?? new Set<number>();
|
||||
requestIds.add(requestId);
|
||||
this.inFlightReactionRequests.delete(key);
|
||||
this.inFlightReactionRequests.set(key, requestIds);
|
||||
while (this.inFlightReactionRequests.size > MAX_TRACKED_REACTION_REQUEST_KEYS) {
|
||||
const oldest = this.inFlightReactionRequests.keys().next();
|
||||
if (oldest.done) break;
|
||||
this.inFlightReactionRequests.delete(oldest.value);
|
||||
this.retiredReactionRequests.delete(oldest.value);
|
||||
}
|
||||
}
|
||||
|
||||
private settleInFlightRequest(key: string, requestId?: number): void {
|
||||
if (requestId == null) return;
|
||||
const requestIds = this.inFlightReactionRequests.get(key);
|
||||
if (!requestIds) return;
|
||||
requestIds.delete(requestId);
|
||||
if (requestIds.size > 0) return;
|
||||
this.inFlightReactionRequests.delete(key);
|
||||
this.retiredReactionRequests.delete(key);
|
||||
}
|
||||
|
||||
private shouldIgnoreFetchResult(key: string, requestId?: number): boolean {
|
||||
|
||||
Reference in new issue
Block a user