mirror of
https://github.com/stablyai/orca.git
synced 2026-10-06 16:02:25 +00:00
fix: drop late remote terminal subscription handles (#4254)
This commit is contained in:
@@ -174,7 +174,7 @@ class RemoteRuntimeTerminalMultiplexer {
|
||||
if (this.connectPromise) {
|
||||
return this.connectPromise
|
||||
}
|
||||
this.connectPromise = new Promise<void>((resolve, reject) => {
|
||||
const connectPromise = new Promise<void>((resolve, reject) => {
|
||||
this.readyResolver = resolve
|
||||
this.readyRejecter = reject
|
||||
void window.api.runtimeEnvironments
|
||||
@@ -193,16 +193,26 @@ class RemoteRuntimeTerminalMultiplexer {
|
||||
}
|
||||
)
|
||||
.then((subscription) => {
|
||||
if (this.connectPromise !== connectPromise || (!this.ready && !this.readyRejecter)) {
|
||||
// Why: close/error can arrive before subscribe() resolves because
|
||||
// preload listens before ipcMain.handle() returns. The multiplexer
|
||||
// may already be released; do not retain the late handle.
|
||||
subscription.unsubscribe()
|
||||
return
|
||||
}
|
||||
this.subscription = subscription
|
||||
this.resolveReadyIfConnected()
|
||||
})
|
||||
.catch((error) => {
|
||||
this.connectPromise = null
|
||||
this.readyResolver = null
|
||||
this.readyRejecter = null
|
||||
if (this.connectPromise === connectPromise) {
|
||||
this.connectPromise = null
|
||||
this.readyResolver = null
|
||||
this.readyRejecter = null
|
||||
}
|
||||
reject(error instanceof Error ? error : new Error(String(error)))
|
||||
})
|
||||
})
|
||||
this.connectPromise = connectPromise
|
||||
return this.connectPromise
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ describe('remote runtime terminal data subscriptions', () => {
|
||||
let callbacks: {
|
||||
onResponse: (response: unknown) => void
|
||||
onBinary?: (bytes: Uint8Array<ArrayBufferLike>) => void
|
||||
onError?: (error: { message: string }) => void
|
||||
onClose?: () => void
|
||||
} | null = null
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -156,4 +158,34 @@ describe('remote runtime terminal data subscriptions', () => {
|
||||
expect(sendBinary).not.toHaveBeenCalled()
|
||||
expect(_getRemoteRuntimeTerminalMultiplexerCountForTest()).toBe(0)
|
||||
})
|
||||
|
||||
it('unsubscribes a late subscription handle after pre-resolution transport close', async () => {
|
||||
let resolveSubscribe!: (handle: {
|
||||
unsubscribe: () => void
|
||||
sendBinary: typeof sendBinary
|
||||
}) => void
|
||||
runtimeSubscribe.mockImplementationOnce((_args: unknown, nextCallbacks: typeof callbacks) => {
|
||||
callbacks = nextCallbacks
|
||||
callbacks?.onClose?.()
|
||||
return new Promise((resolve) => {
|
||||
resolveSubscribe = resolve
|
||||
})
|
||||
})
|
||||
|
||||
const subscriptionPromise = subscribeToRuntimeTerminalData(
|
||||
{ activeRuntimeEnvironmentId: 'env-fallback' },
|
||||
'remote:env-1@@terminal-1',
|
||||
'watcher-1',
|
||||
vi.fn()
|
||||
)
|
||||
|
||||
await expect(subscriptionPromise).rejects.toThrow('Remote Orca runtime closed the connection.')
|
||||
expect(_getRemoteRuntimeTerminalMultiplexerCountForTest()).toBe(0)
|
||||
expect(unsubscribe).not.toHaveBeenCalled()
|
||||
|
||||
resolveSubscribe({ unsubscribe, sendBinary })
|
||||
await Promise.resolve()
|
||||
|
||||
expect(unsubscribe).toHaveBeenCalledOnce()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user