Skip to content

Commit a6adb31

Browse files
tanmaysharma2001Tanmay Sharma
andauthored
fix(realtime): terminate web worker on disconnect to prevent memory leak (#1907)
Co-authored-by: Tanmay Sharma <[email protected]>
1 parent 32d2187 commit a6adb31

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

packages/core/realtime-js/src/RealtimeClient.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,7 @@ export default class RealtimeClient {
667667
this.conn = null
668668
}
669669
this._clearAllTimers()
670+
this._terminateWorker()
670671
this.channels.forEach((channel) => channel.teardown())
671672
}
672673

@@ -720,7 +721,7 @@ export default class RealtimeClient {
720721
this.workerRef = new Worker(objectUrl)
721722
this.workerRef.onerror = (error) => {
722723
this.log('worker', 'worker error', (error as ErrorEvent).message)
723-
this.workerRef!.terminate()
724+
this._terminateWorker()
724725
}
725726
this.workerRef.onmessage = (event) => {
726727
if (event.data.event === 'keepAlive') {
@@ -732,6 +733,18 @@ export default class RealtimeClient {
732733
interval: this.heartbeatIntervalMs,
733734
})
734735
}
736+
737+
/**
738+
* Terminate the Web Worker and clear the reference
739+
* @internal
740+
*/
741+
private _terminateWorker(): void {
742+
if (this.workerRef) {
743+
this.log('worker', 'terminating worker')
744+
this.workerRef.terminate()
745+
this.workerRef = undefined
746+
}
747+
}
735748
/** @internal */
736749
private _onConnClose(event: any) {
737750
this._setConnectionState('disconnected')

packages/core/realtime-js/test/RealtimeClient.worker.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,27 @@ test('creates worker with blob URL when no workerUrl provided', () => {
9898
global.URL.createObjectURL = originalCreateObjectURL
9999
}
100100
})
101+
102+
test('terminates worker on disconnect', () => {
103+
// Establish connection first
104+
client.connect()
105+
106+
// Trigger worker creation
107+
client._onConnOpen()
108+
109+
// Verify worker was created
110+
assert.ok(client.workerRef)
111+
const worker = client.workerRef
112+
113+
// Spy on worker terminate method
114+
const terminateSpy = vi.spyOn(worker, 'terminate')
115+
116+
// Disconnect the client
117+
client.disconnect()
118+
119+
// Verify worker was terminated
120+
expect(terminateSpy).toHaveBeenCalled()
121+
122+
// Verify workerRef was cleared
123+
assert.equal(client.workerRef, undefined)
124+
})

0 commit comments

Comments
 (0)