summaryrefslogtreecommitdiff
path: root/src/misc
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2021-03-18 11:17:05 +0900
committerGitHub <noreply@github.com>2021-03-18 11:17:05 +0900
commit4f249159d310d4296753fcfe8e2bbd390fd9002b (patch)
tree9b483af801a15048265531bcba811c5eb185fb2d /src/misc
parentadd note (diff)
downloadmisskey-4f249159d310d4296753fcfe8e2bbd390fd9002b.tar.gz
misskey-4f249159d310d4296753fcfe8e2bbd390fd9002b.tar.bz2
misskey-4f249159d310d4296753fcfe8e2bbd390fd9002b.zip
Improve chart performance (#7360)
* wip * wip * wip * wip * wip * Update chart.ts * wip * Improve server performance * wip * wip
Diffstat (limited to 'src/misc')
-rw-r--r--src/misc/before-shutdown.ts88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/misc/before-shutdown.ts b/src/misc/before-shutdown.ts
new file mode 100644
index 0000000000..58d0ea5108
--- /dev/null
+++ b/src/misc/before-shutdown.ts
@@ -0,0 +1,88 @@
+// https://gist.github.com/nfantone/1eaa803772025df69d07f4dbf5df7e58
+
+'use strict';
+
+/**
+ * @callback BeforeShutdownListener
+ * @param {string} [signalOrEvent] The exit signal or event name received on the process.
+ */
+
+/**
+ * System signals the app will listen to initiate shutdown.
+ * @const {string[]}
+ */
+const SHUTDOWN_SIGNALS = ['SIGINT', 'SIGTERM'];
+
+/**
+ * Time in milliseconds to wait before forcing shutdown.
+ * @const {number}
+ */
+const SHUTDOWN_TIMEOUT = 15000;
+
+/**
+ * A queue of listener callbacks to execute before shutting
+ * down the process.
+ * @type {BeforeShutdownListener[]}
+ */
+const shutdownListeners = [];
+
+/**
+ * Listen for signals and execute given `fn` function once.
+ * @param {string[]} signals System signals to listen to.
+ * @param {function(string)} fn Function to execute on shutdown.
+ */
+const processOnce = (signals, fn) => {
+ return signals.forEach(sig => process.once(sig, fn));
+};
+
+/**
+ * Sets a forced shutdown mechanism that will exit the process after `timeout` milliseconds.
+ * @param {number} timeout Time to wait before forcing shutdown (milliseconds)
+ */
+const forceExitAfter = timeout => () => {
+ setTimeout(() => {
+ // Force shutdown after timeout
+ console.warn(`Could not close resources gracefully after ${timeout}ms: forcing shutdown`);
+ return process.exit(1);
+ }, timeout).unref();
+};
+
+/**
+ * Main process shutdown handler. Will invoke every previously registered async shutdown listener
+ * in the queue and exit with a code of `0`. Any `Promise` rejections from any listener will
+ * be logged out as a warning, but won't prevent other callbacks from executing.
+ * @param {string} signalOrEvent The exit signal or event name received on the process.
+ */
+async function shutdownHandler(signalOrEvent) {
+ console.warn(`Shutting down: received [${signalOrEvent}] signal`);
+
+ for (const listener of shutdownListeners) {
+ try {
+ await listener(signalOrEvent);
+ } catch (err) {
+ console.warn(`A shutdown handler failed before completing with: ${err.message || err}`);
+ }
+ }
+
+ return process.exit(0);
+}
+
+/**
+ * Registers a new shutdown listener to be invoked before exiting
+ * the main process. Listener handlers are guaranteed to be called in the order
+ * they were registered.
+ * @param {BeforeShutdownListener} listener The shutdown listener to register.
+ * @returns {BeforeShutdownListener} Echoes back the supplied `listener`.
+ */
+export function beforeShutdown(listener) {
+ shutdownListeners.push(listener);
+ return listener;
+}
+
+// Register shutdown callback that kills the process after `SHUTDOWN_TIMEOUT` milliseconds
+// This prevents custom shutdown handlers from hanging the process indefinitely
+processOnce(SHUTDOWN_SIGNALS, forceExitAfter(SHUTDOWN_TIMEOUT));
+
+// Register process shutdown callback
+// Will listen to incoming signal events and execute all registered handlers in the stack
+processOnce(SHUTDOWN_SIGNALS, shutdownHandler);