-
Notifications
You must be signed in to change notification settings - Fork 6.5k
fix(core): add dispose functions to prevent subscription memory leaks #7914
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 1 commit
8142552
3fb83f7
9bcdac9
520ca09
663546a
48a68e6
d1b5d6e
7b271ab
76f0ea6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -100,9 +100,14 @@ export namespace Format { | |||||||||||||||||||||
| return result | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Store unsubscribe functions for cleanup | ||||||||||||||||||||||
| const unsubscribers: Array<() => void> = [] | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export function init() { | ||||||||||||||||||||||
| log.info("init") | ||||||||||||||||||||||
| Bus.subscribe(File.Event.Edited, async (payload) => { | ||||||||||||||||||||||
| // Clean up any existing subscriptions before adding new ones | ||||||||||||||||||||||
| dispose() | ||||||||||||||||||||||
| const unsub = Bus.subscribe(File.Event.Edited, async (payload) => { | ||||||||||||||||||||||
| const file = payload.properties.file | ||||||||||||||||||||||
| log.info("formatting", { file }) | ||||||||||||||||||||||
| const ext = path.extname(file) | ||||||||||||||||||||||
|
|
@@ -133,5 +138,14 @@ export namespace Format { | |||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| unsubscribers.push(unsub) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export function dispose() { | ||||||||||||||||||||||
| for (const unsub of unsubscribers) { | ||||||||||||||||||||||
| unsub() | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| unsubscribers.length = 0 | ||||||||||||||||||||||
|
||||||||||||||||||||||
| unsub() | |
| } | |
| unsubscribers.length = 0 | |
| try { | |
| unsub() | |
| } catch (error) { | |
| log.error("failed to unsubscribe format handler", { error }) | |
| } | |
| } | |
| unsubscribers.splice(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Fixed. Now uses splice(0) for consistency with other modules and wraps each unsubscribe in try-catch for error resilience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Fixed. Now uses splice(0) for consistency with other modules and wraps each unsubscribe in try-catch for error resilience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed! Updated Format.dispose() to use the same pattern: splice(0) before iteration for safe array clearing, plus try-catch around each unsubscribe call for robustness.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,8 +9,14 @@ export namespace Share { | |
|
|
||
| let queue: Promise<void> = Promise.resolve() | ||
| const pending = new Map<string, any>() | ||
| let disposed = false | ||
|
|
||
| // Store unsubscribe functions for cleanup | ||
| const unsubscribers: Array<() => void> = [] | ||
|
|
||
| export async function sync(key: string, content: any) { | ||
| // Skip if disposed | ||
| if (disposed) return | ||
| const [root, ...splits] = key.split("/") | ||
| if (root !== "session") return | ||
| const [sub, sessionID] = splits | ||
|
|
@@ -21,6 +27,8 @@ export namespace Share { | |
| pending.set(key, content) | ||
| queue = queue | ||
| .then(async () => { | ||
| // Check if disposed before processing | ||
| if (disposed) return | ||
hendem marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const content = pending.get(key) | ||
| if (content === undefined) return | ||
| pending.delete(key) | ||
|
|
@@ -46,13 +54,17 @@ export namespace Share { | |
| } | ||
|
|
||
| export function init() { | ||
| Bus.subscribe(Session.Event.Updated, async (evt) => { | ||
| // Clean up any existing subscriptions before adding new ones | ||
| dispose() | ||
| disposed = false | ||
hendem marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
+63
to
+65
|
||
|
|
||
| const unsub1 = Bus.subscribe(Session.Event.Updated, async (evt) => { | ||
| await sync("session/info/" + evt.properties.info.id, evt.properties.info) | ||
| }) | ||
| Bus.subscribe(MessageV2.Event.Updated, async (evt) => { | ||
| const unsub2 = Bus.subscribe(MessageV2.Event.Updated, async (evt) => { | ||
| await sync("session/message/" + evt.properties.info.sessionID + "/" + evt.properties.info.id, evt.properties.info) | ||
| }) | ||
| Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => { | ||
| const unsub3 = Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => { | ||
| await sync( | ||
| "session/part/" + | ||
| evt.properties.part.sessionID + | ||
|
|
@@ -63,6 +75,18 @@ export namespace Share { | |
| evt.properties.part, | ||
| ) | ||
| }) | ||
| unsubscribers.push(unsub1, unsub2, unsub3) | ||
| } | ||
|
|
||
| export function dispose() { | ||
| disposed = true | ||
| for (const unsub of unsubscribers) { | ||
| unsub() | ||
| } | ||
| unsubscribers.length = 0 | ||
| pending.clear() | ||
| queue = Promise.resolve() | ||
hendem marked this conversation as resolved.
Show resolved
Hide resolved
hendem marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| log.info("disposed share subscriptions") | ||
| } | ||
|
|
||
| export const URL = | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.