fix(ext/flash): graceful server startup/shutdown with unsettled promises in mind (#16616)

This PR resets the revert commit made by #16610, bringing back #16383
which attempts to fix the issue happening when we use the flash server
with `--watch` option enabled.
Also, some code changes are made to pass the regression test added in
#16610.
This commit is contained in:
Yusuke Tanaka 2022-11-25 02:38:09 +09:00 committed by GitHub
parent b6f49cf479
commit fd023cf793
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 305 additions and 148 deletions

View file

@ -1167,3 +1167,68 @@ fn run_watch_dynamic_imports() {
check_alive_then_kill(child);
}
// https://github.com/denoland/deno/issues/16267
#[test]
fn run_watch_flash() {
let filename = "watch_flash.js";
let t = TempDir::new();
let file_to_watch = t.path().join(filename);
write(
&file_to_watch,
r#"
console.log("Starting flash server...");
Deno.serve({
onListen() {
console.error("First server is listening");
},
handler: () => {},
port: 4601,
});
"#,
)
.unwrap();
let mut child = util::deno_cmd()
.current_dir(t.path())
.arg("run")
.arg("--watch")
.arg("--unstable")
.arg("--allow-net")
.arg("-L")
.arg("debug")
.arg(&file_to_watch)
.env("NO_COLOR", "1")
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.spawn()
.unwrap();
let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child);
wait_contains("Starting flash server...", &mut stdout_lines);
wait_for(
|m| m.contains("Watching paths") && m.contains(filename),
&mut stderr_lines,
);
write(
&file_to_watch,
r#"
console.log("Restarting flash server...");
Deno.serve({
onListen() {
console.error("Second server is listening");
},
handler: () => {},
port: 4601,
});
"#,
)
.unwrap();
wait_contains("File change detected! Restarting!", &mut stderr_lines);
wait_contains("Restarting flash server...", &mut stdout_lines);
wait_contains("Second server is listening", &mut stderr_lines);
check_alive_then_kill(child);
}

View file

@ -57,32 +57,42 @@ Deno.test(async function httpServerCanResolveHostnames() {
await server;
});
Deno.test(async function httpServerRejectsOnAddrInUse() {
const ac = new AbortController();
// TODO(magurotuna): ignore this case for now because it's flaky on GitHub Actions,
// although it acts as expected when running locally.
// See https://github.com/denoland/deno/pull/16616
Deno.test({ ignore: true }, async function httpServerRejectsOnAddrInUse() {
const ac1 = new AbortController();
const listeningPromise = deferred();
let port: number;
const server = Deno.serve({
handler: (_req) => new Response("ok"),
hostname: "localhost",
port: 4501,
signal: ac.signal,
onListen: onListen(listeningPromise),
onError: createOnErrorCb(ac),
port: 0,
signal: ac1.signal,
onListen: (addr) => {
port = addr.port;
listeningPromise.resolve();
},
onError: createOnErrorCb(ac1),
});
await listeningPromise;
const ac2 = new AbortController();
assertRejects(
() =>
Deno.serve({
handler: (_req) => new Response("ok"),
hostname: "localhost",
port: 4501,
signal: ac.signal,
onListen: onListen(listeningPromise),
onError: createOnErrorCb(ac),
port,
signal: ac2.signal,
}),
Deno.errors.AddrInUse,
);
ac.abort();
ac1.abort();
ac2.abort();
await server;
});