Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down
9 changes: 0 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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"] }
Expand All @@ -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"
5 changes: 3 additions & 2 deletions crates/http-service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
45 changes: 36 additions & 9 deletions crates/http-service/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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};
Expand All @@ -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"];

Expand All @@ -47,7 +50,8 @@ const FASTEDGE_EXECUTION_PANIC: u16 = 533;
pub struct HttpConfig {
pub all_interfaces: bool,
pub port: u16,
pub cancel: Weak<ShutdownHandle>,
#[cfg(target_family = "unix")]
pub cancel: std::sync::Weak<shellflip::ShutdownHandle>,
pub listen_fd: Option<OwnedFd>,
pub backoff: u64,
}
Expand Down Expand Up @@ -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")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How it works in Windows without listener?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code works only for systemd listen_fd. For windows or when service is run without systemd look at next lines: 105-111

} else {
let interface: [u8; 4] = if config.all_interfaces {
[0, 0, 0, 0]
Expand All @@ -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() => {
Expand All @@ -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 {
Expand Down Expand Up @@ -586,6 +602,17 @@ fn app_req_headers(geo: impl Iterator<Item = (SmolStr, SmolStr)>) -> 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;
Expand Down
6 changes: 4 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)?;
Expand Down Expand Up @@ -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,
Expand All @@ -166,6 +167,7 @@ async fn main() -> anyhow::Result<()> {
res?
},
_ = tokio::signal::ctrl_c() => {
#[cfg(target_family = "unix")]
shutdown_coordinator.shutdown().await
}
}
Expand Down