diff --git a/Cargo.lock b/Cargo.lock index ee7293c..36a76b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1761,6 +1761,15 @@ dependencies = [ "dirs 4.0.0", ] +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + [[package]] name = "slab" version = "0.4.9" @@ -1979,6 +1988,7 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", + "signal-hook-registry", "socket2 0.5.5", "tokio-macros", "windows-sys", @@ -2223,6 +2233,7 @@ version = "0.1.1" dependencies = [ "anyhow", "cap-std", + "clap", "dirs 5.0.1", "env_logger", "log", @@ -2278,9 +2289,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi-cap-std-sync" -version = "15.0.0" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3542b8d238a3de6c9986218af842f1e8f950ca7c4707aee9d0dd83002577a759" +checksum = "a4328de5cf2a0debfc48216fe9c2747badc64957837641f5836cd8b3d48d73f0" dependencies = [ "anyhow", "async-trait", @@ -2301,9 +2312,9 @@ dependencies = [ [[package]] name = "wasi-common" -version = "15.0.0" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a362c9dbdc5eb0809ce9db09e7b76805fea3ddaf2b8ff41a0e5c805935736205" +checksum = "84f6774ec9e464b7373f683bc57ff87fcca5fd26a7d6bdb7438fb2f56a545aa6" dependencies = [ "anyhow", "bitflags 2.4.1", @@ -2321,9 +2332,9 @@ dependencies = [ [[package]] name = "wasi-tokio" -version = "15.0.0" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385503c0e4502dc5cbd7fdfe25f2d87a5dd19dd1cdd7e3bc5184146713bba554" +checksum = "499ab8a1825b795a60cbfddc75a8f77dbfe9688575f8ade2e151f664869d5691" dependencies = [ "anyhow", "cap-std", @@ -2659,9 +2670,9 @@ dependencies = [ [[package]] name = "wasmtime-wasi" -version = "15.0.0" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f94342fc932695027cdfa0500a62a680879bdad495b36490887b1564124e53" +checksum = "eff3f4ad191a5e6d002bb5bffa3e2931a58984da9b30e57b48f353848748cf80" dependencies = [ "anyhow", "async-trait", @@ -2772,9 +2783,9 @@ dependencies = [ [[package]] name = "wiggle" -version = "15.0.0" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35b5a36af7e0a7d68fd6c080e78803b34c3105caa3f743dff2fc8db2fac4ab71" +checksum = "f91028b241e692fdf30627ac10ba9d5ac378353ea4119b4f904ac95177057a44" dependencies = [ "anyhow", "async-trait", @@ -2787,9 +2798,9 @@ dependencies = [ [[package]] name = "wiggle-generate" -version = "15.0.0" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f5a763e4801e83c438e7fa6abdd5c38d735194c2a94e2f2ccdcc66456cefee" +checksum = "5e8b3d76531994513671b2ec3b29fd342bf041e2282945bb6c52eebe6aa9e7da" dependencies = [ "anyhow", "heck", @@ -2802,9 +2813,9 @@ dependencies = [ [[package]] name = "wiggle-macro" -version = "15.0.0" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58262f5ac3a8ea686d4b940aa9f976f26c7e4e980aa8ac378f29274cb8638e33" +checksum = "c189fe00c67f61bb330827f2abab1af9b5925c7929535cd13a68d265ec20b02d" dependencies = [ "proc-macro2", "quote", diff --git a/wacker-cli/src/main.rs b/wacker-cli/src/main.rs index 0732690..7672303 100644 --- a/wacker-cli/src/main.rs +++ b/wacker-cli/src/main.rs @@ -9,9 +9,7 @@ use wacker_api::config::SOCK_PATH; #[derive(Parser)] #[command(name = "wacker")] -#[command(author = "ia")] -#[command(version = "0.1.1")] -#[command(about = "wacker client", long_about = None)] +#[command(author, version, about, long_about = None)] struct Wacker { #[clap(subcommand)] subcommand: Subcommand, @@ -35,7 +33,7 @@ enum Subcommand { impl Wacker { /// Executes the command. - pub async fn execute(self) -> Result<()> { + async fn execute(self) -> Result<()> { let home_dir = dirs::home_dir().expect("Can't get home dir"); let path = home_dir.join(SOCK_PATH); @@ -59,5 +57,5 @@ impl Wacker { #[tokio::main] async fn main() -> Result<()> { - return Wacker::parse().execute().await; + Wacker::parse().execute().await } diff --git a/wacker/Cargo.toml b/wacker/Cargo.toml index c42f69f..4bc8be8 100644 --- a/wacker/Cargo.toml +++ b/wacker/Cargo.toml @@ -19,11 +19,11 @@ path = "src/main.rs" [dependencies] wacker-api = { path = "../wacker-api", version = "0.1.1" } anyhow = "1.0.75" -tokio = { version = "1.34.0", features = ["rt", "rt-multi-thread", "macros"] } +tokio = { version = "1.34.0", features = ["rt", "rt-multi-thread", "macros", "signal"] } tokio-stream = { version = "0.1.14", features = ["net"] } -wasi-common = "15.0.0" +wasi-common = "15.0.1" wasmtime = { version = "15.0.1", features = ["cranelift"] } -wasmtime-wasi = { version = "15.0.0", features = ["tokio"] } +wasmtime-wasi = { version = "15.0.1", features = ["tokio"] } tonic = "0.10.2" dirs = "5.0.1" log = "0.4.20" @@ -31,3 +31,4 @@ env_logger = "0.10.1" cap-std = "2.0.0" rand = "0.8.5" sled = "0.34.7" +clap = { version = "4.4.11", features = ["derive"] } diff --git a/wacker/src/main.rs b/wacker/src/main.rs index 7a9449b..b96da7c 100644 --- a/wacker/src/main.rs +++ b/wacker/src/main.rs @@ -3,42 +3,65 @@ mod run; use crate::module::Service; use anyhow::Result; +use clap::Parser; use log::info; use std::fs; use tokio::net::UnixListener; +use tokio::signal; use tokio_stream::wrappers::UnixListenerStream; use tonic::transport::Server; -use wacker_api::{config::SOCK_PATH, modules_server::ModulesServer}; +use wacker_api::{ + config::{DB_PATH, SOCK_PATH}, + modules_server::ModulesServer, +}; -#[tokio::main] -async fn main() -> Result<()> { - let home_dir = dirs::home_dir().expect("Can't get home dir"); - let binding = home_dir.join(SOCK_PATH); - let path = binding.as_path(); - let parent_path = path.parent().unwrap(); +#[derive(Parser)] +#[command(name = "wackerd")] +#[command(author, version, about, long_about = None)] +struct WackerDaemon {} - if !parent_path.exists() { - fs::create_dir_all(parent_path)?; - } - if path.exists() { - fs::remove_file(path).expect("Failed to remove existing socket file"); - } +impl WackerDaemon { + async fn execute(self) -> Result<()> { + let home_dir = dirs::home_dir().expect("Can't get home dir"); + let binding = home_dir.join(SOCK_PATH); + let path = binding.as_path(); + let parent_path = path.parent().unwrap(); + + if !parent_path.exists() { + fs::create_dir_all(parent_path)?; + } + if path.exists() { + fs::remove_file(path)?; + } - let uds = UnixListener::bind(path)?; - let uds_stream = UnixListenerStream::new(uds); + let uds = UnixListener::bind(path)?; + let uds_stream = UnixListenerStream::new(uds); - let inner = Service::new(home_dir).await?; + let db = sled::open(home_dir.join(DB_PATH))?; + let inner = Service::new(home_dir, db.clone()).await?; - let env = env_logger::Env::default() - .filter_or("LOG_LEVEL", "info") - .write_style_or("LOG_STYLE", "never"); - env_logger::init_from_env(env); + let env = env_logger::Env::default() + .filter_or("LOG_LEVEL", "info") + .write_style_or("LOG_STYLE", "never"); + env_logger::init_from_env(env); - info!("server listening on {:?}", path); - Server::builder() - .add_service(ModulesServer::new(inner)) - .serve_with_incoming(uds_stream) - .await?; + info!("server listening on {:?}", path); + Server::builder() + .add_service(ModulesServer::new(inner)) + .serve_with_incoming_shutdown(uds_stream, async { + signal::ctrl_c().await.expect("failed to listen for event"); + println!(); + info!("Shutting down the server"); + fs::remove_file(path).expect("failed to remove existing socket file"); + db.flush_async().await.expect("failed to flush the db"); + }) + .await?; - Ok(()) + Ok(()) + } +} + +#[tokio::main] +async fn main() -> Result<()> { + WackerDaemon::parse().execute().await } diff --git a/wacker/src/module.rs b/wacker/src/module.rs index 52fd5b0..330f7df 100644 --- a/wacker/src/module.rs +++ b/wacker/src/module.rs @@ -13,7 +13,7 @@ use tokio::{ task, }; use tonic::{Request, Response, Status}; -use wacker_api::config::{DB_PATH, LOGS_DIR}; +use wacker_api::config::LOGS_DIR; pub struct Service { db: Db, @@ -31,14 +31,13 @@ struct InnerModule { } impl Service { - pub async fn new(home_dir: PathBuf) -> Result { + pub async fn new(home_dir: PathBuf, db: Db) -> Result { if let Err(e) = create_dir(home_dir.join(LOGS_DIR)) { if e.kind() != ErrorKind::AlreadyExists { bail!("create logs dir failed: {}", e); } } - let db = sled::open(home_dir.join(DB_PATH))?; // Create an environment shared by all wasm execution. This contains // the `Engine` we are executing. let env = Environment::new()?;