- From: bojavou <notifications@github.com>
- Date: Tue, 04 Jul 2023 17:14:48 -0700
- To: whatwg/dom <dom@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/dom/issues/1215@github.com>
Some systems distinguish between a graceful shutdown and a forceful termination. This distinction cannot be delivered through `AbortController`. It would be nice if the same channel could be used to deliver both. The current interface might extend to this cleanly, without breaking anything. The delivered `Event` could provide a boolean `.force` indicating whether a forceful abort was requested or not. `AbortController.prototype.abort()` could take the option `{ force: true }` to request a forceful abort. A second call to `abort()` could be allowed, for requesting forceful abort after a standard abort was already requested. 2 levels of strength seem sufficient. I've never seen a use for further distinctions. Some usage patterns. * Request forceful abort immediately. Everything is terminated as quickly as possible. This might be tied to a more forceful user control, eg Kill vs Cancel. ```js const reason = new Error('User clicked Kill Now') controller.abort(reason, { force: true }) ``` ```js const reason = new Error('User clicked Cancel') controller.abort(reason) ``` ```js function aborted (event) { if (event.force) { kill() } else { cancel() } } ``` * Request standard abort with a time limit. Request forceful abort if it times out. This might be useful where closing a connection can take a long time. The close logic can have retries to tolerate transient network errors, with delays between them. If the process drags on too long, terminate. ```js process.on('SIGINT', () => { // Await close of everything watching the signal Promise.allSettled(clients.map(client => client.done)) .then(() => { process.exit() }) // Request standard shutdown controller.abort() // Time out standard shutdown in 5 seconds // Unref the timer to prevent it keeping the process alive const timer = setTimeout(() => { const reason = new Error('Closing connection timed out') controller.abort(reason, { force: true }) }, 5000) timer.unref() }) ``` * Offer users 2 levels of interrupt. This is a common pattern in the CLI interface of servers. The first CTRL+C initiates a graceful shutdown: the server stops accepting new connections and waits for existing connections to complete normally. A second CTRL+C during graceful shutdown terminates all open connections without waiting for completion and shuts down immediately. ```sh $ ./server Serving 112 requests Interrupt received, shutting down Completed 52/112 requests Second interrupt received, terminating open connections ``` ```js let shuttingDown = false process.on('SIGINT', () => { if (!shuttingDown) { // First interrupt, start graceful shutdown shuttingDown = true program.closed.then(() => { process.exit() }) controller.abort() } else { // Second interrupt, kill everything now controller.abort(undefined, { force: true }) } }) ``` -- Reply to this email directly or view it on GitHub: https://github.com/whatwg/dom/issues/1215 You are receiving this because you are subscribed to this thread. Message ID: <whatwg/dom/issues/1215@github.com>
Received on Wednesday, 5 July 2023 00:14:54 UTC