Skip to content

Commit f956b84

Browse files
committed
watch: handle errors and changes during compile gracefully
1 parent cc29381 commit f956b84

File tree

2 files changed

+20
-11
lines changed

2 files changed

+20
-11
lines changed

crates/spirv-builder/src/watch.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::{SpirvBuilder, SpirvBuilderError, leaf_deps};
22
use notify::{Event, RecommendedWatcher, RecursiveMode, Watcher};
33
use rustc_codegen_spirv_types::CompileResult;
4+
use std::sync::mpsc::TrySendError;
45
use std::{
56
collections::HashSet,
67
path::PathBuf,
@@ -40,19 +41,21 @@ impl SpirvWatcher {
4041
return Err(SpirvWatcherError::WatchWithPrintMetadata.into());
4142
}
4243

43-
let (tx, rx) = sync_channel(0);
44+
let (tx, rx) = sync_channel(1);
4445
let watcher =
4546
notify::recommended_watcher(move |result: notify::Result<Event>| match result {
4647
Ok(event) => match event.kind {
4748
notify::EventKind::Any
4849
| notify::EventKind::Create(_)
4950
| notify::EventKind::Modify(_)
5051
| notify::EventKind::Remove(_)
51-
| notify::EventKind::Other => {
52-
if let Err(err) = tx.try_send(()) {
53-
log::error!("send error: {err:?}");
54-
}
55-
}
52+
| notify::EventKind::Other => match tx.try_send(()) {
53+
Ok(_) => (),
54+
// disconnect is fine, SpirvWatcher is currently dropping
55+
Err(TrySendError::Disconnected(_)) => (),
56+
// full is fine, we just need to send a single event anyway
57+
Err(TrySendError::Full(_)) => (),
58+
},
5659
notify::EventKind::Access(_) => {}
5760
},
5861
Err(err) => log::error!("notify error: {err:?}"),
@@ -78,7 +81,7 @@ impl SpirvWatcher {
7881
return self.recv_first_result();
7982
}
8083

81-
self.rx.recv().expect("watcher should be alive");
84+
self.rx.recv().map_err(|_| SpirvWatcherError::WatcherDied)?;
8285
let metadata_file = crate::invoke_rustc(&self.builder)?;
8386
let result = self.builder.parse_metadata_file(&metadata_file)?;
8487

@@ -97,7 +100,7 @@ impl SpirvWatcher {
97100
.watch(watch_path, RecursiveMode::Recursive)
98101
.map_err(SpirvWatcherError::NotifyFailed)?;
99102
let path = loop {
100-
self.rx.recv().expect("watcher should be alive");
103+
self.rx.recv().map_err(|_| SpirvWatcherError::WatcherDied)?;
101104
match crate::invoke_rustc(&self.builder) {
102105
Ok(path) => break path,
103106
Err(err) => log::error!("{err}"),
@@ -136,4 +139,6 @@ pub enum SpirvWatcherError {
136139
WatchWithPrintMetadata,
137140
#[error("could not notify for changes: {0}")]
138141
NotifyFailed(#[from] notify::Error),
142+
#[error("watcher died and closed channel")]
143+
WatcherDied,
139144
}

examples/runners/wgpu/src/lib.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272

7373
use clap::Parser;
7474
use clap::ValueEnum;
75+
use spirv_builder::SpirvBuilderError;
7576
use std::borrow::Cow;
7677
use strum::{Display, EnumString};
7778

@@ -183,9 +184,12 @@ fn maybe_watch(
183184
let shader_modules = handle_compile_result(first_compile);
184185
std::thread::spawn(move || {
185186
loop {
186-
let compile_result = watcher.recv().unwrap();
187-
let modules = handle_compile_result(compile_result);
188-
f(modules);
187+
match watcher.recv() {
188+
Ok(compile_result) => {
189+
f(handle_compile_result(compile_result));
190+
}
191+
Err(e) => println!("Shader compiling failed: {e}"),
192+
}
189193
}
190194
});
191195
shader_modules

0 commit comments

Comments
 (0)