(id: string, userId: string)
| 153 | }; |
| 154 | |
| 155 | export const destroyRemoteBrowser = async (id: string, userId: string): Promise<boolean> => { |
| 156 | clearRecordingTimeout(id); |
| 157 | |
| 158 | const DESTROY_TIMEOUT = 30000; |
| 159 | |
| 160 | const destroyPromise = (async () => { |
| 161 | try { |
| 162 | const browserSession = browserPool.getRemoteBrowser(id); |
| 163 | if (!browserSession) { |
| 164 | logger.log('info', `Browser with id: ${id} not found, may have already been destroyed`); |
| 165 | return true; |
| 166 | } |
| 167 | |
| 168 | logger.log('debug', `Switching off the browser with id: ${id}`); |
| 169 | |
| 170 | try { |
| 171 | await browserSession.switchOff(); |
| 172 | } catch (switchOffError) { |
| 173 | logger.log('warn', `Error switching off browser ${id}: ${switchOffError}`); |
| 174 | } |
| 175 | |
| 176 | try { |
| 177 | const namespace = io.of(id); |
| 178 | |
| 179 | const sockets = await namespace.fetchSockets(); |
| 180 | for (const socket of sockets) { |
| 181 | socket.disconnect(true); |
| 182 | } |
| 183 | |
| 184 | namespace.removeAllListeners(); |
| 185 | |
| 186 | await new Promise(resolve => setTimeout(resolve, 100)); |
| 187 | |
| 188 | const nsps = (io as any)._nsps; |
| 189 | if (nsps && nsps.has(`/${id}`)) { |
| 190 | const ns = nsps.get(`/${id}`); |
| 191 | if (ns && ns.sockets && ns.sockets.size === 0) { |
| 192 | nsps.delete(`/${id}`); |
| 193 | logger.log('debug', `Deleted empty namespace /${id} from io._nsps Map`); |
| 194 | } else { |
| 195 | logger.log('warn', `Namespace /${id} still has ${ns?.sockets?.size || 0} sockets, skipping manual deletion`); |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | logger.log('debug', `Cleaned up socket namespace for browser ${id}`); |
| 200 | } catch (namespaceCleanupError: any) { |
| 201 | logger.log('warn', `Error cleaning up socket namespace for browser ${id}: ${namespaceCleanupError.message}`); |
| 202 | } |
| 203 | |
| 204 | return browserPool.deleteRemoteBrowser(id); |
| 205 | } catch (error) { |
| 206 | const errorMessage = error instanceof Error ? error.message : String(error); |
| 207 | logger.log('error', `Failed to destroy browser ${id}: ${errorMessage}`); |
| 208 | |
| 209 | try { |
| 210 | return browserPool.deleteRemoteBrowser(id); |
| 211 | } catch (deleteError) { |
| 212 | logger.log('error', `Failed to delete browser ${id} from pool: ${deleteError}`); |
no test coverage detected