feat: added wrapper for native background worker

This commit is contained in:
əlemi 2022-06-05 20:05:39 +02:00
parent 0fed3fff95
commit 4465c672ab
Signed by: alemi
GPG key ID: A4895B84D311642C
4 changed files with 61 additions and 2 deletions

View file

@ -18,8 +18,19 @@ chrono = { version = "0.4", features = ["wasmbind"] }
eframe = { version = "0.18", features = ["persistence"] } eframe = { version = "0.18", features = ["persistence"] }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
jq-rs = "0.4"
rusqlite = { version = "0.27" }
ehttp = "0.2.0" 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] [target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6" console_error_panic_hook = "0.1.6"
tracing-wasm = "0.2" tracing-wasm = "0.2"
[env]
JQ_LIB_DIR="/usr/lib"

View file

@ -1,15 +1,22 @@
mod app; mod app;
mod util;
use app::App; use app::App;
use crate::util::worker::{BackgroundWorker, NativeBackgroundWorker};
// When compiling natively: // When compiling natively:
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
fn main() { fn main() {
let native_options = eframe::NativeOptions::default(); 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", "2b2t queue stats",
native_options, native_options,
Box::new(|cc| Box::new(App::new(cc))), Box::new(|cc| Box::new(App::new(cc))),
); );
// worker.stop();
} }

1
src/util/mod.rs Normal file
View file

@ -0,0 +1 @@
pub(crate) mod worker;

40
src/util/worker.rs Normal file
View file

@ -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<T>(&self, task:T) where T : std::future::Future<Output = ()> + 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<bool>,
worker : std::thread::JoinHandle<bool>,
}
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::<bool>();
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<T>(&self, task:T) where T : std::future::Future<Output = ()> + 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");
}
}