diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9df0df5..10252e9 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -40,6 +40,10 @@ jobs: os: macos-latest target: aarch64-apple-darwin + - build: windows + os: windows-latest + target: x86_64-pc-windows-msvc + steps: - name: Clone repo uses: actions/checkout@v4 @@ -74,7 +78,7 @@ jobs: 7z a "$dirname.zip" "$dirname" certutil -hashfile "$dirname.zip" SHA256 > "$dirname.zip.sha256" echo "ASSET=$dirname.zip" >> $GITHUB_ENV - echo "ASSET_SUM=$dirname.tar.gz.sha256" >> $GITHUB_ENV + echo "ASSET_SUM=$dirname.zip.sha256" >> $GITHUB_ENV else tar -czf "$dirname.tar.gz" "$dirname" shasum -a 256 "$dirname.tar.gz" > "$dirname.tar.gz.sha256" diff --git a/Cargo.lock b/Cargo.lock index 60a5337..3c03a11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -518,9 +518,7 @@ dependencies = [ "shellflip", "smol_str", "tokio", - "tokio-util", "wasmtime", - "wasmtime-wasi", ] [[package]] @@ -1455,7 +1453,6 @@ dependencies = [ "tokio-util", "tracing", "tracing-test", - "uri", "wasi-common", "wasmtime", "wasmtime-wasi", @@ -3434,12 +3431,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" -[[package]] -name = "uri" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5c61fea9e6205d0d14c7e6efe252f15ed404da4cbdbe4ecd1de0a4d7241829f" - [[package]] name = "url" version = "2.5.4" diff --git a/Cargo.toml b/Cargo.toml index 10c10af..f8d427b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,6 @@ clap = { version = "4", features = ["derive"] } moka = { version = "0.12", features = ["sync"] } smol_str = { version = "0.2.1", features = ["serde"] } anyhow = "1.0" -shellflip = "2.1.0" [workspace.lints.rust] unused_extern_crates = 'warn' @@ -47,9 +46,7 @@ anyhow = { workspace = true } hyper = { workspace = true } http = { workspace = true } tokio = { workspace = true } -tokio-util = { workspace = true } wasmtime = { workspace = true } -wasmtime-wasi = { workspace = true } smol_str = { workspace = true } async-trait = {workspace = true} clap = { version = "4.5", features = ["derive"] } @@ -62,6 +59,7 @@ secret = { path = "crates/secret" } hyper-tls = "0.6" hyper-util = { version = "0.1", features = ["client", "client-legacy", "http1", "tokio"] } http-body-util = "0.1" -shellflip = {workspace = true} bytesize = "1.3.0" +[target.'cfg(target_family = "unix")'.dependencies] +shellflip = "2.1.1" diff --git a/crates/http-service/Cargo.toml b/crates/http-service/Cargo.toml index f6e77a1..26a2bd2 100644 --- a/crates/http-service/Cargo.toml +++ b/crates/http-service/Cargo.toml @@ -39,9 +39,10 @@ async-trait = "0.1" wasmtime-wasi-http = "20.0.2" hyper-util = { version = "0.1", features = ["server", "server-graceful"] } http-body-util = "0.1" -shellflip = {workspace = true} bytes = "1.6" -uri = "0.4" + +[target.'cfg(target_family = "unix")'.dependencies] +shellflip = "2.1.1" [dev-dependencies] claims = "0.7" diff --git a/crates/http-service/src/lib.rs b/crates/http-service/src/lib.rs index f8085a6..f7e93a7 100644 --- a/crates/http-service/src/lib.rs +++ b/crates/http-service/src/lib.rs @@ -1,6 +1,5 @@ use std::net::SocketAddr; -use std::os::fd::OwnedFd; -use std::sync::{Arc, Weak}; +use std::sync::Arc; use std::time::Duration; pub use crate::executor::ExecutorFactory; @@ -24,7 +23,6 @@ use runtime::{ WasmEngine, WasmEngineBuilder, }; use secret::SecretStrategy; -use shellflip::{ShutdownHandle, ShutdownSignal}; use smol_str::SmolStr; use state::HttpState; use tokio::{net::TcpListener, time::error::Elapsed}; @@ -35,6 +33,11 @@ pub mod state; pub(crate) static TRACEPARENT: &str = "traceparent"; +#[cfg(target_family = "unix")] +type OwnedFd = std::os::fd::OwnedFd; +#[cfg(not(target_family = "unix"))] +type OwnedFd = std::os::raw::c_int; + #[cfg(feature = "metrics")] const HTTP_LABEL: &[&str; 1] = &["http"]; @@ -47,7 +50,8 @@ const FASTEDGE_EXECUTION_PANIC: u16 = 533; pub struct HttpConfig { pub all_interfaces: bool, pub port: u16, - pub cancel: Weak, + #[cfg(target_family = "unix")] + pub cancel: std::sync::Weak, pub listen_fd: Option, pub backoff: u64, } @@ -86,10 +90,17 @@ where /// Run hyper http service async fn run(self, config: Self::Config) -> Result<()> { + #[allow(unused_variables)] let listener = if let Some(fd) = config.listen_fd { - let listener = std::net::TcpListener::from(fd); - listener.set_nonblocking(true)?; - TcpListener::from_std(listener)? + #[cfg(target_family = "unix")] + { + let listener = std::net::TcpListener::from(fd); + listener.set_nonblocking(true)?; + TcpListener::from_std(listener)? + } + + #[cfg(not(target_family = "unix"))] + panic!("listen_fd is not supported on this platform") } else { let interface: [u8; 4] = if config.all_interfaces { [0, 0, 0, 0] @@ -99,17 +110,22 @@ where let listen_addr = SocketAddr::from((interface, config.port)); TcpListener::bind(listen_addr).await? }; + let listen_addr = listener.local_addr()?; tracing::info!("Listening on http://{}", listen_addr); let mut backoff = 1; let self_ = Arc::new(self); let graceful = hyper_util::server::graceful::GracefulShutdown::new(); + #[cfg(target_family = "unix")] let mut signal = config .cancel .upgrade() - .map(|s| ShutdownSignal::from(s.as_ref())) + .map(|s| shellflip::ShutdownSignal::from(s.as_ref())) .unwrap_or_default(); + #[cfg(not(target_family = "unix"))] + let signal = signal::Signal {}; + loop { tokio::select! { conn = listener.accept() => { @@ -131,7 +147,7 @@ where } }); - let connection = http1::Builder::new().keep_alive(true).serve_connection(io, service); + let connection = http1::Builder::new().keep_alive(true).serve_connection(io, service); let connection = graceful.watch(connection); tokio::spawn(async move { if let Err(error) = connection.await { @@ -586,6 +602,17 @@ fn app_req_headers(geo: impl Iterator) -> HeaderMap { headers } +#[cfg(not(target_family = "unix"))] +pub(crate) mod signal { + pub(crate) struct Signal; + + impl Signal { + pub(crate) async fn on_shutdown(&self) { + tokio::signal::ctrl_c().await.expect("ctrl-c"); + } + } +} + #[cfg(test)] mod tests { use test_case::test_case; diff --git a/src/main.rs b/src/main.rs index 3064978..a0a91d6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,6 @@ use runtime::{ componentize_if_necessary, App, ContextT, ExecutorCache, PreCompiledLoader, Router, SecretValue, WasiVersion, WasmConfig, WasmEngine, }; -use shellflip::ShutdownCoordinator; use smol_str::{SmolStr, ToSmolStr}; use std::collections::HashMap; use std::path::PathBuf; @@ -95,7 +94,8 @@ struct CliContext { #[tokio::main] async fn main() -> anyhow::Result<()> { pretty_env_logger::init(); - let shutdown_coordinator = ShutdownCoordinator::new(); + #[cfg(target_family = "unix")] + let shutdown_coordinator = shellflip::ShutdownCoordinator::new(); let args = Cli::parse(); let config = WasmConfig::default(); let engine = Engine::new(&config)?; @@ -157,6 +157,7 @@ async fn main() -> anyhow::Result<()> { let http = http.run(HttpConfig { all_interfaces: false, port: run.port, + #[cfg(target_family = "unix")] cancel: shutdown_coordinator.handle_weak(), listen_fd: None, backoff: 64, @@ -166,6 +167,7 @@ async fn main() -> anyhow::Result<()> { res? }, _ = tokio::signal::ctrl_c() => { + #[cfg(target_family = "unix")] shutdown_coordinator.shutdown().await } }