Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ walkdir = "2.3.2"
# NOTE: we don't depend on this crate but we need to activate this feature otherwise it's super slow
walrus = { version = "0.26.1", features = ["parallel"] }
wasm-bindgen-cli-support = "0.2.100"
xtask-watch = "0.3.2"
xtask-watch = "0.3.3"

[target.'cfg(unix)'.dependencies]
libc = "0.2.112"
Expand Down
25 changes: 22 additions & 3 deletions src/dev_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::{
sync::Arc,
thread,
};
use xtask_watch::WatchLock;
Comment thread
cecton marked this conversation as resolved.

type RequestHandler = Arc<dyn Fn(Request) -> Result<()> + Send + Sync + 'static>;

Expand Down Expand Up @@ -352,6 +353,8 @@ impl DevServer {
}
let dist_dir = self.dist_dir.clone().unwrap();

let watch_lock = self.watch.lock();

let watch_process = {
// mem::take so we can pass &self to build_command while the fields are empty.
let pre_hooks = std::mem::take(&mut self.pre_hooks);
Expand All @@ -373,7 +376,8 @@ impl DevServer {
format!("cannot create dist directory `{}`", dist_dir.display())
})?;
let watch = self.watch.exclude_path(&dist_dir);
let handle = std::thread::spawn(|| match watch.run(commands) {

let handle = std::thread::spawn(move || match watch.run(commands) {
Ok(()) => log::trace!("Starting to watch"),
Err(err) => log::error!("an error occurred when starting to watch: {err}"),
});
Expand All @@ -385,15 +389,23 @@ impl DevServer {
};

if let Some(handler) = self.request_handler {
serve(self.ip, self.port, dist_dir, self.not_found_path, handler)
.context("an error occurred when starting to serve")?;
serve(
self.ip,
self.port,
dist_dir,
self.not_found_path,
handler,
watch_lock,
)
.context("an error occurred when starting to serve")?;
} else {
serve(
self.ip,
self.port,
dist_dir,
self.not_found_path,
Arc::new(default_request_handler),
watch_lock,
)
.context("an error occurred when starting to serve")?;
}
Expand Down Expand Up @@ -428,6 +440,7 @@ fn serve(
dist_dir: PathBuf,
not_found_path: Option<PathBuf>,
handler: RequestHandler,
watch_lock: WatchLock,
) -> Result<()> {
let address = SocketAddr::new(ip, port);
let listener = TcpListener::bind(address).context("cannot bind to the given address")?;
Expand All @@ -450,8 +463,14 @@ fn serve(
let handler = handler.clone();
let dist_dir = dist_dir.clone();
Comment thread
cecton marked this conversation as resolved.
let not_found_path = not_found_path.clone();
let watch_lock = watch_lock.clone();
thread::spawn(move || {
// Read the request header *before* acquiring the watch lock so that connections
// can be accepted and parsed while a rebuild is in progress. This reduces
// perceived latency: the response is dispatched immediately once the build
// finishes rather than having to re-parse the header afterward.
let header = warn_not_fail!(read_header(&stream));
let _guard = watch_lock.acquire();
let request = Request {
stream: &mut stream,
header: header.as_ref(),
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ use std::process::Command;
#[cfg(not(target_arch = "wasm32"))]
pub use xtask_watch::{
anyhow, cargo_metadata, cargo_metadata::camino, clap, metadata, package, xtask_command, Watch,
WatchLock, WatchLockGuard,
};

#[cfg(not(target_arch = "wasm32"))]
Expand Down
Loading