mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
share HTTP server between threads (attempt 2) (#6652)
This commit is contained in:
parent
75d9913b22
commit
2fe315bfb1
1 changed files with 73 additions and 39 deletions
|
@ -48,7 +48,7 @@ lazy_static! {
|
||||||
r"[\x1b\x9b][\[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]"
|
r"[\x1b\x9b][\[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]"
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
static ref GUARD: Mutex<()> = Mutex::new(());
|
static ref GUARD: Mutex<HttpServerCount> = Mutex::new(HttpServerCount::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root_path() -> PathBuf {
|
pub fn root_path() -> PathBuf {
|
||||||
|
@ -418,36 +418,17 @@ fn custom_headers(path: warp::path::Peek, f: warp::fs::File) -> Box<dyn Reply> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct HttpServerGuard<'a> {
|
#[derive(Default)]
|
||||||
#[allow(dead_code)]
|
struct HttpServerCount {
|
||||||
g: MutexGuard<'a, ()>,
|
count: usize,
|
||||||
test_server: Child,
|
test_server: Option<Child>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Drop for HttpServerGuard<'a> {
|
impl HttpServerCount {
|
||||||
fn drop(&mut self) {
|
fn inc(&mut self) {
|
||||||
match self.test_server.try_wait() {
|
self.count += 1;
|
||||||
Ok(None) => {
|
if self.test_server.is_none() {
|
||||||
self.test_server.kill().expect("failed to kill test_server");
|
assert_eq!(self.count, 1);
|
||||||
let _ = self.test_server.wait();
|
|
||||||
}
|
|
||||||
Ok(Some(status)) => panic!("test_server exited unexpectedly {}", status),
|
|
||||||
Err(e) => panic!("test_server error: {}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Starts target/debug/test_server when the returned guard is dropped, the server
|
|
||||||
/// will be killed.
|
|
||||||
pub fn http_server<'a>() -> HttpServerGuard<'a> {
|
|
||||||
// TODO(bartlomieju) Allow tests to use the http server in parallel.
|
|
||||||
let r = GUARD.lock();
|
|
||||||
let g = if let Err(poison_err) = r {
|
|
||||||
// If panics happened, ignore it. This is for tests.
|
|
||||||
poison_err.into_inner()
|
|
||||||
} else {
|
|
||||||
r.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
println!("test_server starting...");
|
println!("test_server starting...");
|
||||||
let mut test_server = Command::new(test_server_path())
|
let mut test_server = Command::new(test_server_path())
|
||||||
|
@ -455,7 +436,6 @@ pub fn http_server<'a>() -> HttpServerGuard<'a> {
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("failed to execute test_server");
|
.expect("failed to execute test_server");
|
||||||
|
|
||||||
let stdout = test_server.stdout.as_mut().unwrap();
|
let stdout = test_server.stdout.as_mut().unwrap();
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
let lines = BufReader::new(stdout).lines();
|
let lines = BufReader::new(stdout).lines();
|
||||||
|
@ -468,8 +448,62 @@ pub fn http_server<'a>() -> HttpServerGuard<'a> {
|
||||||
panic!(maybe_line.unwrap_err());
|
panic!(maybe_line.unwrap_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.test_server = Some(test_server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HttpServerGuard { test_server, g }
|
fn dec(&mut self) {
|
||||||
|
assert!(self.count > 0);
|
||||||
|
self.count -= 1;
|
||||||
|
if self.count == 0 {
|
||||||
|
let mut test_server = self.test_server.take().unwrap();
|
||||||
|
match test_server.try_wait() {
|
||||||
|
Ok(None) => {
|
||||||
|
test_server.kill().expect("failed to kill test_server");
|
||||||
|
let _ = test_server.wait();
|
||||||
|
}
|
||||||
|
Ok(Some(status)) => {
|
||||||
|
panic!("test_server exited unexpectedly {}", status)
|
||||||
|
}
|
||||||
|
Err(e) => panic!("test_server error: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for HttpServerCount {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
assert_eq!(self.count, 0);
|
||||||
|
assert!(self.test_server.is_none());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lock_http_server<'a>() -> MutexGuard<'a, HttpServerCount> {
|
||||||
|
let r = GUARD.lock();
|
||||||
|
if let Err(poison_err) = r {
|
||||||
|
// If panics happened, ignore it. This is for tests.
|
||||||
|
poison_err.into_inner()
|
||||||
|
} else {
|
||||||
|
r.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HttpServerGuard {}
|
||||||
|
|
||||||
|
impl Drop for HttpServerGuard {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let mut g = lock_http_server();
|
||||||
|
g.dec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a reference to a shared target/debug/test_server subprocess. When the
|
||||||
|
/// last instance of the HttpServerGuard is dropped, the subprocess will be
|
||||||
|
/// killed.
|
||||||
|
pub fn http_server() -> HttpServerGuard {
|
||||||
|
let mut g = lock_http_server();
|
||||||
|
g.inc();
|
||||||
|
HttpServerGuard {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to strip ansi codes.
|
/// Helper function to strip ansi codes.
|
||||||
|
|
Loading…
Add table
Reference in a new issue