diff --git a/Cargo.toml b/Cargo.toml index ce9521d..c186629 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,8 +18,19 @@ chrono = { version = "0.4", features = ["wasmbind"] } eframe = { version = "0.18", features = ["persistence"] } serde = { version = "1", features = ["derive"] } serde_json = "1" +jq-rs = "0.4" +rusqlite = { version = "0.27" } ehttp = "0.2.0" -# web: +reqwest = { version = "0.11", features = ["json"] } + +# native only dependancies: +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +tokio = { version = "1", features = ["full"] } # TODO do we need full features? + +# web only dependancies: [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.6" tracing-wasm = "0.2" + +[env] +JQ_LIB_DIR="/usr/lib" diff --git a/src/main.rs b/src/main.rs index 8f94d92..4c46ef4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,22 @@ mod app; +mod util; use app::App; +use crate::util::worker::{BackgroundWorker, NativeBackgroundWorker}; + // When compiling natively: #[cfg(not(target_arch = "wasm32"))] fn main() { let native_options = eframe::NativeOptions::default(); - eframe::run_native( + let worker = NativeBackgroundWorker::start(); + + eframe::run_native( // TODO replace this with a loop that ends so we can cleanly exit the background worker "2b2t queue stats", native_options, Box::new(|cc| Box::new(App::new(cc))), ); + + // worker.stop(); } diff --git a/src/util/mod.rs b/src/util/mod.rs new file mode 100644 index 0000000..4ff7f34 --- /dev/null +++ b/src/util/mod.rs @@ -0,0 +1 @@ +pub(crate) mod worker; \ No newline at end of file diff --git a/src/util/worker.rs b/src/util/worker.rs new file mode 100644 index 0000000..cfb3557 --- /dev/null +++ b/src/util/worker.rs @@ -0,0 +1,40 @@ +use tokio::{runtime::Runtime, sync::oneshot::Sender}; + +pub(crate) trait BackgroundWorker { + fn start() -> Self; // TODO make it return an error? Can we even do anything without a background worker + fn task(&self, task:T) where T : std::future::Future + core::marker::Send + 'static; + fn stop(self); // TODO make it return an error? Can we even do anything without a background worker +} + +pub(crate) struct NativeBackgroundWorker { + runtime : Runtime, + end_tx : Sender, + worker : std::thread::JoinHandle, +} + +impl BackgroundWorker for NativeBackgroundWorker { + fn start() -> Self { + let runtime = Runtime::new().expect("Failed creating Tokio runtime"); + let (end_tx, end_rx) = tokio::sync::oneshot::channel::(); + let r_handle = runtime.handle().clone(); + let worker = std::thread::spawn(move ||{ + r_handle.block_on(async { + end_rx.await.expect("Error shutting down") + }) + }); + NativeBackgroundWorker { + runtime : runtime, + end_tx : end_tx, + worker : worker, + } + } + + fn task(&self, task:T) where T : std::future::Future + core::marker::Send + 'static { + self.runtime.spawn(task); + } + + fn stop(self) { + self.end_tx.send(true).expect("Failed signaling termination"); + self.worker.join().expect("Failed joining main worker thread"); + } +} \ No newline at end of file