-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FR] signal to catch exit via deno run --watch #14424
Comments
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. |
I'm on Deno Here's my This covers everything I need and shuts down gracefully if I hit import { __DEV__ } from "../config.ts";
import { signal } from "../deps.ts";
export type AppShutdownReason = "ERROR" | "NORMAL" | "SIGNAL";
export type AppShutdownHandler = (reason: AppShutdownReason) => Promise<void>;
const SIGNALS = {
darwin: ["SIGINT", "SIGTERM"] as Deno.Signal[],
linux: ["SIGINT", "SIGTERM"] as Deno.Signal[],
/** Only SIGINT (ctrl+c) and SIGBREAK (ctrl+break) are supported. */
windows: ["SIGINT"] as Deno.Signal[],
};
const [listenSignalFirst, ...listenSignalRest] = SIGNALS[Deno.build.os];
const listener = signal(listenSignalFirst, ...listenSignalRest);
let shutdownHandler: AppShutdownHandler | undefined;
let shuttingDown = false;
export async function listenForShutdown(handler?: AppShutdownHandler) {
shutdownHandler = handler;
if (__DEV__) {
addEventListener("unload", function handleDevShutdown() {
onShutdown("SIGNAL");
});
}
// CONSIDER: Should we try/catch errors while listening for shutdown signals?
for await (const _ of listener) {
await shutdown("SIGNAL");
}
}
function onShutdown(reason: AppShutdownReason) {
const handler = shutdownHandler;
if (handler) {
return handler(reason);
}
return Promise.resolve();
}
export async function shutdown(
reason: AppShutdownReason = "NORMAL",
code?: number,
) {
if (shuttingDown) {
return;
}
shuttingDown = true;
const exitCode = code ?? (reason === "ERROR" ? 1 : 0);
try {
console.log("");
console.log(`Shutting down...`);
await onShutdown(reason).catch((err) => {
console.error("Shutdown error.", err);
});
listener.dispose();
console.log("Goodbye.");
} catch (ex) {
console.error(ex);
} finally {
if (__DEV__ && exitCode !== 0) {
// Don't exit the process in development mode. Let the runner restart it.
console.error(`Exit code: ${exitCode}`);
} else {
Deno.exit(exitCode);
}
}
} |
Just wanted to leave one more useful comment for anyone dealing with temp files in development... If you set the if (__DEV__) {
Deno.env.set("TMPDIR", `${Deno.cwd()}/tmp`);
} and now all temp files are created in a |
One small problem I have with this shutdown code: If my |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. |
|
I've been searching for a way to flush to async data stores before restarting, and haven't been able to find one. The restart happens before promises resolve. A signal or event would be very useful. Would you please consider reopening this? |
One option is to close https://matklad.github.io/2023/10/11/unix-structured-concurrency.html |
During development in a docker container network, the deno server is started with deno run --watch. If project files are saved when deno is servicing a request, db transaction etc. there is no opportunity to clean up and if a source file is changed the process is killed instantly and restarted.
I have tried the following:
and also
But I can never capture deno going down. This is quite problematic during development/testing.
Suggested solution
An early suggestions for watch implementation mentioned here suggested the possibility to intercept SIGUSR1; that would seem a good solution, with the signal configurable. During watch, allow a configurable grace period (default 2s) before deno restarts, along with a console message to indicate 'Waiting for clean shutdown...'
The text was updated successfully, but these errors were encountered: