| 571 | } |
| 572 | |
| 573 | async function cleanup(reason, err, { exit = false } = {}) { |
| 574 | if (quitting && exit) { |
| 575 | DEBUG.verbose && console.log(chalk.cyan(`Cleanup already in progress for exit. Reason: ${reason}`)); |
| 576 | return; |
| 577 | } |
| 578 | console.log(chalk.cyan(`\nInitiating shutdown sequence. Reason: ${reason}`)); |
| 579 | if (err) { |
| 580 | console.error(chalk.red('Error during operation or shutdown:'), err instanceof Error ? err.stack : err); |
| 581 | } |
| 582 | |
| 583 | if (exit) quitting = true; |
| 584 | |
| 585 | DEBUG.verbose && console.log(chalk.yellow(`Cleanup called. Reason: ${reason}`)); |
| 586 | |
| 587 | Archivist.shutdown(); // Signal archivist to stop its work |
| 588 | LibraryServer.stop(); // Stop the HTTP server |
| 589 | |
| 590 | // Note: We don't explicitly kill the browser here if it was launched by us. |
| 591 | // Its 'exit' handler calls cleanup. If the user chose 'connect', we don't own the process. |
| 592 | // If 'shutdown_all_and_exit' was chosen, browsers were killed before this. |
| 593 | |
| 594 | if (exit) { |
| 595 | console.log(chalk.cyan(`All components signaled to stop. Exiting in 3 seconds...`)); |
| 596 | await sleep(3000); |
| 597 | process.exit(err instanceof Error ? 1 : 0); |
| 598 | } |
| 599 | } |