| 235 | |
| 236 | let cleanupInProgress = false; |
| 237 | const cleanup = async (reason: string | number) => { |
| 238 | if (cleanupInProgress) return; |
| 239 | cleanupInProgress = true; |
| 240 | |
| 241 | output.debug( |
| 242 | typeof reason === 'number' |
| 243 | ? `Exiting with code ${reason}, shutting down...` |
| 244 | : `Received ${reason}, shutting down...` |
| 245 | ); |
| 246 | |
| 247 | clearTimeout(timeout); |
| 248 | controller.abort(); |
| 249 | |
| 250 | if (lockAcquired) { |
| 251 | releaseDevLock(cwd); |
| 252 | } |
| 253 | |
| 254 | await devServer.stop(); |
| 255 | |
| 256 | let exitCode: number; |
| 257 | if (typeof reason === 'number') { |
| 258 | exitCode = reason; |
| 259 | } else { |
| 260 | switch (reason) { |
| 261 | case 'SIGINT': |
| 262 | exitCode = 130; |
| 263 | break; |
| 264 | case 'SIGTERM': |
| 265 | exitCode = 143; |
| 266 | break; |
| 267 | case 'SIGHUP': |
| 268 | exitCode = 129; |
| 269 | break; |
| 270 | default: |
| 271 | exitCode = 0; |
| 272 | } |
| 273 | } |
| 274 | |
| 275 | process.exit(exitCode); |
| 276 | }; |
| 277 | |
| 278 | process.on('SIGTERM', async () => await cleanup('SIGTERM')); |
| 279 | process.on('SIGINT', async () => await cleanup('SIGINT')); |