Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/dev/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { isTest, isCI } from "std-env";
import { NitroDevApp } from "./app.ts";
import { writeDevBuildInfo } from "../build/info.ts";

const SHUTDOWN_TIMEOUT = 5000;

export function createDevServer(nitro: Nitro): NitroDevServer {
return new NitroDevServer(nitro);
}
Expand All @@ -34,6 +36,8 @@ export class NitroDevServer extends NitroDevApp implements RunnerRPCHooks {
#building?: boolean = true; // Assume initial build will start soon
#buildError?: unknown;
#reloadPromise?: Promise<void>;
#shuttingDown: boolean = false;
#closing: boolean = false;

constructor(nitro: Nitro) {
super(nitro, async (event) => {
Expand Down Expand Up @@ -76,6 +80,9 @@ export class NitroDevServer extends NitroDevApp implements RunnerRPCHooks {
});
});
this.#manager.onClose((_runner, cause) => {
if (this.#shuttingDown) {
return;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
this.#workerError = cause;
if (this.#workerRetries++ < 3) {
this.nitro.logger.info("Restarting dev worker...", cause ? `Cause: ${cause}` : "");
Expand Down Expand Up @@ -146,6 +153,9 @@ export class NitroDevServer extends NitroDevApp implements RunnerRPCHooks {
}

async close() {
this.#closing = true;
await this.#reloadPromise?.catch(() => {});
await this.#shutdownWorker();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
await Promise.all(
[
Promise.all(this.#listeners.map((l) => l.close())).then(() => {
Expand All @@ -164,6 +174,9 @@ export class NitroDevServer extends NitroDevApp implements RunnerRPCHooks {
}

reload() {
if (this.#closing) {
return;
}
const nextReload = (this.#reloadPromise ?? Promise.resolve())
.catch(() => {})
.then(() => this.#reload());
Expand All @@ -175,6 +188,7 @@ export class NitroDevServer extends NitroDevApp implements RunnerRPCHooks {
}

async #reload() {
await this.#shutdownWorker();
const runnerName =
this.nitro.options.devServer.runner || process.env.NITRO_DEV_RUNNER || "node-worker";
const runner = await loadRunner(runnerName as RunnerName, {
Expand All @@ -200,6 +214,42 @@ export class NitroDevServer extends NitroDevApp implements RunnerRPCHooks {

// #region Private Methods

async #shutdownWorker() {
if (!this.#manager.ready) {
return;
}
this.#shuttingDown = true;
try {
await new Promise<void>((resolve) => {
const done = () => {
clearTimeout(timer);
this.#manager.offMessage(listener);
resolve();
};
const timer = setTimeout(() => {
this.nitro.logger.warn("Dev worker did not shut down in time, force closing it...");
done();
}, SHUTDOWN_TIMEOUT);
const listener = (message: any) => {
if (message?.event === "exit") {
done();
}
};
this.#manager.onMessage(listener);
try {
this.#manager.sendMessage({ event: "shutdown" });
} catch (error) {
this.nitro.logger.warn(
`Could not send shutdown message to the dev worker: ${error instanceof Error ? error.message : String(error)}`
);
done();
}
});
} finally {
this.#shuttingDown = false;
}
}

async #waitForBuild() {
const timeout = isTest || isCI ? 60_000 : 6000;
await this.#manager.waitForReady(timeout);
Expand Down
Loading