mirror of https://github.com/fafhrd91/actix-net
Compare commits
No commits in common. "064da0e3ffbfc2be674c8aa157a489459a749d53" and "d61b33928debf441d387d2d802dd5707542e7133" have entirely different histories.
064da0e3ff
...
d61b33928d
|
@ -1,8 +0,0 @@
|
||||||
version: "0.2"
|
|
||||||
words:
|
|
||||||
- actix
|
|
||||||
- addrs
|
|
||||||
- mptcp
|
|
||||||
- nonblocking
|
|
||||||
- oneshot
|
|
||||||
- rustup
|
|
|
@ -8,4 +8,3 @@ updates:
|
||||||
directory: /
|
directory: /
|
||||||
schedule:
|
schedule:
|
||||||
interval: weekly
|
interval: weekly
|
||||||
versioning-strategy: lockfile-only
|
|
||||||
|
|
|
@ -59,12 +59,12 @@ jobs:
|
||||||
echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV
|
echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Install Rust (${{ matrix.version }})
|
- name: Install Rust (${{ matrix.version }})
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
|
uses: actions-rust-lang/setup-rust-toolchain@v1.11.0
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ matrix.version }}
|
toolchain: ${{ matrix.version }}
|
||||||
|
|
||||||
- name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean
|
- name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean
|
||||||
uses: taiki-e/install-action@v2.50.10
|
uses: taiki-e/install-action@v2.49.45
|
||||||
with:
|
with:
|
||||||
tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean
|
tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean
|
||||||
|
|
||||||
|
@ -116,12 +116,12 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Rust (nightly)
|
- name: Install Rust (nightly)
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
|
uses: actions-rust-lang/setup-rust-toolchain@v1.11.0
|
||||||
with:
|
with:
|
||||||
toolchain: nightly
|
toolchain: nightly
|
||||||
|
|
||||||
- name: Install cargo-hack & cargo-minimal-versions
|
- name: Install cargo-hack & cargo-minimal-versions
|
||||||
uses: taiki-e/install-action@v2.50.10
|
uses: taiki-e/install-action@v2.49.45
|
||||||
with:
|
with:
|
||||||
tool: cargo-hack,cargo-minimal-versions
|
tool: cargo-hack,cargo-minimal-versions
|
||||||
|
|
||||||
|
|
|
@ -68,12 +68,12 @@ jobs:
|
||||||
echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV
|
echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Install Rust (${{ matrix.version.name }})
|
- name: Install Rust (${{ matrix.version.name }})
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
|
uses: actions-rust-lang/setup-rust-toolchain@v1.11.0
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ matrix.version.version }}
|
toolchain: ${{ matrix.version.version }}
|
||||||
|
|
||||||
- name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean
|
- name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean
|
||||||
uses: taiki-e/install-action@v2.50.10
|
uses: taiki-e/install-action@v2.49.45
|
||||||
with:
|
with:
|
||||||
tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean
|
tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean
|
||||||
|
|
||||||
|
@ -120,12 +120,12 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Rust (nightly)
|
- name: Install Rust (nightly)
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
|
uses: actions-rust-lang/setup-rust-toolchain@v1.11.0
|
||||||
with:
|
with:
|
||||||
toolchain: nightly
|
toolchain: nightly
|
||||||
|
|
||||||
- name: Install just
|
- name: Install just
|
||||||
uses: taiki-e/install-action@v2.50.10
|
uses: taiki-e/install-action@v2.49.45
|
||||||
with:
|
with:
|
||||||
tool: just
|
tool: just
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,12 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
|
uses: actions-rust-lang/setup-rust-toolchain@v1.11.0
|
||||||
with:
|
with:
|
||||||
components: llvm-tools-preview
|
components: llvm-tools-preview
|
||||||
|
|
||||||
- name: Install cargo-llvm-cov
|
- name: Install cargo-llvm-cov
|
||||||
uses: taiki-e/install-action@v2.50.10
|
uses: taiki-e/install-action@v2.49.45
|
||||||
with:
|
with:
|
||||||
tool: cargo-llvm-cov
|
tool: cargo-llvm-cov
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ jobs:
|
||||||
run: cargo llvm-cov --workspace --all-features --codecov --output-path codecov.json
|
run: cargo llvm-cov --workspace --all-features --codecov --output-path codecov.json
|
||||||
|
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
uses: codecov/codecov-action@v5.4.2
|
uses: codecov/codecov-action@v5.4.0
|
||||||
with:
|
with:
|
||||||
files: codecov.json
|
files: codecov.json
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|
|
@ -18,7 +18,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
|
- uses: actions-rust-lang/setup-rust-toolchain@v1.11.0
|
||||||
with:
|
with:
|
||||||
toolchain: nightly
|
toolchain: nightly
|
||||||
components: rustfmt
|
components: rustfmt
|
||||||
|
@ -35,7 +35,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
|
- uses: actions-rust-lang/setup-rust-toolchain@v1.11.0
|
||||||
with: { components: clippy }
|
with: { components: clippy }
|
||||||
|
|
||||||
- uses: giraffate/clippy-action@v1.0.1
|
- uses: giraffate/clippy-action@v1.0.1
|
||||||
|
@ -51,12 +51,12 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Rust (${{ vars.RUST_VERSION_EXTERNAL_TYPES }})
|
- name: Install Rust (${{ vars.RUST_VERSION_EXTERNAL_TYPES }})
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
|
uses: actions-rust-lang/setup-rust-toolchain@v1.11.0
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }}
|
toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }}
|
||||||
|
|
||||||
- name: Install just
|
- name: Install just
|
||||||
uses: taiki-e/install-action@v2.50.10
|
uses: taiki-e/install-action@v2.49.45
|
||||||
with:
|
with:
|
||||||
tool: just
|
tool: just
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -187,7 +187,10 @@ impl SystemRunner {
|
||||||
|
|
||||||
match exit_code {
|
match exit_code {
|
||||||
0 => Ok(()),
|
0 => Ok(()),
|
||||||
nonzero => Err(io::Error::other(format!("Non-zero exit code: {}", nonzero))),
|
nonzero => Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!("Non-zero exit code: {}", nonzero),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +199,8 @@ impl SystemRunner {
|
||||||
let SystemRunner { rt, stop_rx, .. } = self;
|
let SystemRunner { rt, stop_rx, .. } = self;
|
||||||
|
|
||||||
// run loop
|
// run loop
|
||||||
rt.block_on(stop_rx).map_err(io::Error::other)
|
rt.block_on(stop_rx)
|
||||||
|
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves a reference to the underlying [Actix runtime](crate::Runtime) associated with this
|
/// Retrieves a reference to the underlying [Actix runtime](crate::Runtime) associated with this
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
## 2.6.0
|
|
||||||
|
|
||||||
- Add `ServerBuilder::shutdown_signal()` method.
|
|
||||||
- Minimum supported Rust version (MSRV) is now 1.74.
|
- Minimum supported Rust version (MSRV) is now 1.74.
|
||||||
|
|
||||||
## 2.5.1
|
## 2.5.1
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "actix-server"
|
name = "actix-server"
|
||||||
version = "2.6.0"
|
version = "2.5.1"
|
||||||
authors = [
|
authors = [
|
||||||
"Nikolay Kim <fafhrd91@gmail.com>",
|
"Nikolay Kim <fafhrd91@gmail.com>",
|
||||||
"Rob Ede <robjtede@icloud.com>",
|
"Rob Ede <robjtede@icloud.com>",
|
||||||
|
@ -44,10 +44,7 @@ actix-rt = "2.8"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
futures-util = { version = "0.3.17", default-features = false, features = ["sink", "async-await-macro"] }
|
futures-util = { version = "0.3.17", default-features = false, features = ["sink", "async-await-macro"] }
|
||||||
pretty_env_logger = "0.5"
|
pretty_env_logger = "0.5"
|
||||||
static_assertions = "1"
|
tokio = { version = "1.44.2", features = ["io-util", "rt-multi-thread", "macros", "fs"] }
|
||||||
tokio = { version = "1.44.2", features = ["io-util", "rt-multi-thread", "macros", "fs", "time"] }
|
|
||||||
tokio-util = "0.7"
|
|
||||||
tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] }
|
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
<!-- prettier-ignore-start -->
|
<!-- prettier-ignore-start -->
|
||||||
|
|
||||||
[](https://crates.io/crates/actix-server)
|
[](https://crates.io/crates/actix-server)
|
||||||
[](https://docs.rs/actix-server/2.6.0)
|
[](https://docs.rs/actix-server/2.5.1)
|
||||||
[](https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html)
|
[](https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html)
|
||||||

|

|
||||||
<br />
|
<br />
|
||||||
[](https://deps.rs/crate/actix-server/2.6.0)
|
[](https://deps.rs/crate/actix-server/2.5.1)
|
||||||

|

|
||||||
[](https://discord.gg/NWpN5mmg3x)
|
[](https://discord.gg/NWpN5mmg3x)
|
||||||
|
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
//! Demonstrates use of the `ServerBuilder::shutdown_signal` method using `tokio-util`s
|
|
||||||
//! `CancellationToken` helper using a nonsensical timer. In practice, this cancellation token would
|
|
||||||
//! be wired throughout your application and typically triggered by OS signals elsewhere.
|
|
||||||
|
|
||||||
use std::{io, time::Duration};
|
|
||||||
|
|
||||||
use actix_rt::net::TcpStream;
|
|
||||||
use actix_server::Server;
|
|
||||||
use actix_service::fn_service;
|
|
||||||
use tokio_util::sync::CancellationToken;
|
|
||||||
use tracing::level_filters::LevelFilter;
|
|
||||||
use tracing_subscriber::{prelude::*, EnvFilter};
|
|
||||||
|
|
||||||
async fn run(stop_signal: CancellationToken) -> io::Result<()> {
|
|
||||||
tracing_subscriber::registry()
|
|
||||||
.with(tracing_subscriber::fmt::layer())
|
|
||||||
.with(
|
|
||||||
EnvFilter::builder()
|
|
||||||
.with_default_directive(LevelFilter::INFO.into())
|
|
||||||
.from_env_lossy(),
|
|
||||||
)
|
|
||||||
.init();
|
|
||||||
|
|
||||||
let addr = ("127.0.0.1", 8080);
|
|
||||||
tracing::info!("starting server on port: {}", &addr.0);
|
|
||||||
|
|
||||||
Server::build()
|
|
||||||
.bind("shutdown-signal", addr, || {
|
|
||||||
fn_service(|_stream: TcpStream| async { Ok::<_, io::Error>(()) })
|
|
||||||
})?
|
|
||||||
.shutdown_signal(stop_signal.cancelled_owned())
|
|
||||||
.workers(2)
|
|
||||||
.run()
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> io::Result<()> {
|
|
||||||
let stop_signal = CancellationToken::new();
|
|
||||||
|
|
||||||
tokio::spawn({
|
|
||||||
let stop_signal = stop_signal.clone();
|
|
||||||
async move {
|
|
||||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
|
||||||
stop_signal.cancel();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
run(stop_signal).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
|
@ -76,7 +76,7 @@ impl Accept {
|
||||||
let accept_handle = thread::Builder::new()
|
let accept_handle = thread::Builder::new()
|
||||||
.name("actix-server acceptor".to_owned())
|
.name("actix-server acceptor".to_owned())
|
||||||
.spawn(move || accept.poll_with(&mut sockets))
|
.spawn(move || accept.poll_with(&mut sockets))
|
||||||
.map_err(io::Error::other)?;
|
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
|
||||||
|
|
||||||
Ok((waker_queue, handles_server, accept_handle))
|
Ok((waker_queue, handles_server, accept_handle))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::{future::Future, io, num::NonZeroUsize, time::Duration};
|
use std::{io, num::NonZeroUsize, time::Duration};
|
||||||
|
|
||||||
use actix_rt::net::TcpStream;
|
use actix_rt::net::TcpStream;
|
||||||
use futures_core::future::BoxFuture;
|
|
||||||
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
|
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -40,7 +39,6 @@ pub struct ServerBuilder {
|
||||||
pub(crate) mptcp: MpTcp,
|
pub(crate) mptcp: MpTcp,
|
||||||
pub(crate) exit: bool,
|
pub(crate) exit: bool,
|
||||||
pub(crate) listen_os_signals: bool,
|
pub(crate) listen_os_signals: bool,
|
||||||
pub(crate) shutdown_signal: Option<BoxFuture<'static, ()>>,
|
|
||||||
pub(crate) cmd_tx: UnboundedSender<ServerCommand>,
|
pub(crate) cmd_tx: UnboundedSender<ServerCommand>,
|
||||||
pub(crate) cmd_rx: UnboundedReceiver<ServerCommand>,
|
pub(crate) cmd_rx: UnboundedReceiver<ServerCommand>,
|
||||||
pub(crate) worker_config: ServerWorkerConfig,
|
pub(crate) worker_config: ServerWorkerConfig,
|
||||||
|
@ -66,7 +64,6 @@ impl ServerBuilder {
|
||||||
mptcp: MpTcp::Disabled,
|
mptcp: MpTcp::Disabled,
|
||||||
exit: false,
|
exit: false,
|
||||||
listen_os_signals: true,
|
listen_os_signals: true,
|
||||||
shutdown_signal: None,
|
|
||||||
cmd_tx,
|
cmd_tx,
|
||||||
cmd_rx,
|
cmd_rx,
|
||||||
worker_config: ServerWorkerConfig::default(),
|
worker_config: ServerWorkerConfig::default(),
|
||||||
|
@ -173,41 +170,6 @@ impl ServerBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specify shutdown signal from a future.
|
|
||||||
///
|
|
||||||
/// Using this method will prevent OS signal handlers being set up.
|
|
||||||
///
|
|
||||||
/// Typically, a `CancellationToken` will be used, but any future _can_ be.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// # use std::io;
|
|
||||||
/// # use tokio::net::TcpStream;
|
|
||||||
/// # use actix_server::Server;
|
|
||||||
/// # async fn run() -> io::Result<()> {
|
|
||||||
/// use actix_service::fn_service;
|
|
||||||
/// use tokio_util::sync::CancellationToken;
|
|
||||||
///
|
|
||||||
/// let stop_signal = CancellationToken::new();
|
|
||||||
///
|
|
||||||
/// Server::build()
|
|
||||||
/// .bind("shutdown-signal", "127.0.0.1:12345", || {
|
|
||||||
/// fn_service(|_stream: TcpStream| async { Ok::<_, io::Error>(()) })
|
|
||||||
/// })?
|
|
||||||
/// .shutdown_signal(stop_signal.cancelled_owned())
|
|
||||||
/// .run()
|
|
||||||
/// .await
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
pub fn shutdown_signal<Fut>(mut self, shutdown_signal: Fut) -> Self
|
|
||||||
where
|
|
||||||
Fut: Future<Output = ()> + Send + 'static,
|
|
||||||
{
|
|
||||||
self.shutdown_signal = Some(Box::pin(shutdown_signal));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Timeout for graceful workers shutdown in seconds.
|
/// Timeout for graceful workers shutdown in seconds.
|
||||||
///
|
///
|
||||||
/// After receiving a stop signal, workers have this much time to finish serving requests.
|
/// After receiving a stop signal, workers have this much time to finish serving requests.
|
||||||
|
@ -408,6 +370,9 @@ pub(super) fn bind_addr<S: ToSocketAddrs>(
|
||||||
} else if let Some(err) = opt_err.take() {
|
} else if let Some(err) = opt_err.take() {
|
||||||
Err(err)
|
Err(err)
|
||||||
} else {
|
} else {
|
||||||
Err(io::Error::other("Can not bind to address."))
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"Can not bind to address.",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ use crate::{
|
||||||
builder::ServerBuilder,
|
builder::ServerBuilder,
|
||||||
join_all::join_all,
|
join_all::join_all,
|
||||||
service::InternalServiceFactory,
|
service::InternalServiceFactory,
|
||||||
signals::{OsSignals, SignalKind, StopSignal},
|
signals::{SignalKind, Signals},
|
||||||
waker_queue::{WakerInterest, WakerQueue},
|
waker_queue::{WakerInterest, WakerQueue},
|
||||||
worker::{ServerWorker, ServerWorkerConfig, WorkerHandleServer},
|
worker::{ServerWorker, ServerWorkerConfig, WorkerHandleServer},
|
||||||
ServerHandle,
|
ServerHandle,
|
||||||
|
@ -210,12 +210,7 @@ impl ServerInner {
|
||||||
let (waker_queue, worker_handles, accept_handle) = Accept::start(sockets, &builder)?;
|
let (waker_queue, worker_handles, accept_handle) = Accept::start(sockets, &builder)?;
|
||||||
|
|
||||||
let mux = ServerEventMultiplexer {
|
let mux = ServerEventMultiplexer {
|
||||||
signal_fut: builder.shutdown_signal.map(StopSignal::Cancel).or_else(|| {
|
signal_fut: (builder.listen_os_signals).then(Signals::new),
|
||||||
builder
|
|
||||||
.listen_os_signals
|
|
||||||
.then(OsSignals::new)
|
|
||||||
.map(StopSignal::Os)
|
|
||||||
}),
|
|
||||||
cmd_rx: builder.cmd_rx,
|
cmd_rx: builder.cmd_rx,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -320,16 +315,7 @@ impl ServerInner {
|
||||||
|
|
||||||
fn map_signal(signal: SignalKind) -> ServerCommand {
|
fn map_signal(signal: SignalKind) -> ServerCommand {
|
||||||
match signal {
|
match signal {
|
||||||
SignalKind::Cancel => {
|
SignalKind::Int => {
|
||||||
info!("Cancellation token/channel received; starting graceful shutdown");
|
|
||||||
ServerCommand::Stop {
|
|
||||||
graceful: true,
|
|
||||||
completion: None,
|
|
||||||
force_system_stop: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SignalKind::OsInt => {
|
|
||||||
info!("SIGINT received; starting forced shutdown");
|
info!("SIGINT received; starting forced shutdown");
|
||||||
ServerCommand::Stop {
|
ServerCommand::Stop {
|
||||||
graceful: false,
|
graceful: false,
|
||||||
|
@ -338,7 +324,7 @@ impl ServerInner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalKind::OsTerm => {
|
SignalKind::Term => {
|
||||||
info!("SIGTERM received; starting graceful shutdown");
|
info!("SIGTERM received; starting graceful shutdown");
|
||||||
ServerCommand::Stop {
|
ServerCommand::Stop {
|
||||||
graceful: true,
|
graceful: true,
|
||||||
|
@ -347,7 +333,7 @@ impl ServerInner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalKind::OsQuit => {
|
SignalKind::Quit => {
|
||||||
info!("SIGQUIT received; starting forced shutdown");
|
info!("SIGQUIT received; starting forced shutdown");
|
||||||
ServerCommand::Stop {
|
ServerCommand::Stop {
|
||||||
graceful: false,
|
graceful: false,
|
||||||
|
@ -361,7 +347,7 @@ impl ServerInner {
|
||||||
|
|
||||||
struct ServerEventMultiplexer {
|
struct ServerEventMultiplexer {
|
||||||
cmd_rx: UnboundedReceiver<ServerCommand>,
|
cmd_rx: UnboundedReceiver<ServerCommand>,
|
||||||
signal_fut: Option<StopSignal>,
|
signal_fut: Option<Signals>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stream for ServerEventMultiplexer {
|
impl Stream for ServerEventMultiplexer {
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use std::{
|
use std::{
|
||||||
fmt,
|
fmt,
|
||||||
future::Future,
|
future::Future,
|
||||||
pin::{pin, Pin},
|
pin::Pin,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
|
|
||||||
use futures_core::future::BoxFuture;
|
|
||||||
use tracing::trace;
|
use tracing::trace;
|
||||||
|
|
||||||
/// Types of process signals.
|
/// Types of process signals.
|
||||||
|
@ -13,51 +12,28 @@ use tracing::trace;
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
#[allow(dead_code)] // variants are never constructed on non-unix
|
#[allow(dead_code)] // variants are never constructed on non-unix
|
||||||
pub(crate) enum SignalKind {
|
pub(crate) enum SignalKind {
|
||||||
/// Cancellation token or channel.
|
/// `SIGINT`
|
||||||
Cancel,
|
Int,
|
||||||
|
|
||||||
/// OS `SIGINT`.
|
/// `SIGTERM`
|
||||||
OsInt,
|
Term,
|
||||||
|
|
||||||
/// OS `SIGTERM`.
|
/// `SIGQUIT`
|
||||||
OsTerm,
|
Quit,
|
||||||
|
|
||||||
/// OS `SIGQUIT`.
|
|
||||||
OsQuit,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for SignalKind {
|
impl fmt::Display for SignalKind {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.write_str(match self {
|
f.write_str(match self {
|
||||||
SignalKind::Cancel => "Cancellation token or channel",
|
SignalKind::Int => "SIGINT",
|
||||||
SignalKind::OsInt => "SIGINT",
|
SignalKind::Term => "SIGTERM",
|
||||||
SignalKind::OsTerm => "SIGTERM",
|
SignalKind::Quit => "SIGQUIT",
|
||||||
SignalKind::OsQuit => "SIGQUIT",
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) enum StopSignal {
|
|
||||||
/// OS signal handling is configured.
|
|
||||||
Os(OsSignals),
|
|
||||||
|
|
||||||
/// Cancellation token or channel.
|
|
||||||
Cancel(BoxFuture<'static, ()>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Future for StopSignal {
|
|
||||||
type Output = SignalKind;
|
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
||||||
match self.get_mut() {
|
|
||||||
StopSignal::Os(os_signals) => pin!(os_signals).poll(cx),
|
|
||||||
StopSignal::Cancel(cancel) => pin!(cancel).poll(cx).map(|()| SignalKind::Cancel),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Process signal listener.
|
/// Process signal listener.
|
||||||
pub(crate) struct OsSignals {
|
pub(crate) struct Signals {
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
signals: futures_core::future::BoxFuture<'static, std::io::Result<()>>,
|
signals: futures_core::future::BoxFuture<'static, std::io::Result<()>>,
|
||||||
|
|
||||||
|
@ -65,14 +41,14 @@ pub(crate) struct OsSignals {
|
||||||
signals: Vec<(SignalKind, actix_rt::signal::unix::Signal)>,
|
signals: Vec<(SignalKind, actix_rt::signal::unix::Signal)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OsSignals {
|
impl Signals {
|
||||||
/// Constructs an OS signal listening future.
|
/// Constructs an OS signal listening future.
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
trace!("setting up OS signal listener");
|
trace!("setting up OS signal listener");
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
{
|
{
|
||||||
OsSignals {
|
Signals {
|
||||||
signals: Box::pin(actix_rt::signal::ctrl_c()),
|
signals: Box::pin(actix_rt::signal::ctrl_c()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,9 +58,9 @@ impl OsSignals {
|
||||||
use actix_rt::signal::unix;
|
use actix_rt::signal::unix;
|
||||||
|
|
||||||
let sig_map = [
|
let sig_map = [
|
||||||
(unix::SignalKind::interrupt(), SignalKind::OsInt),
|
(unix::SignalKind::interrupt(), SignalKind::Int),
|
||||||
(unix::SignalKind::terminate(), SignalKind::OsTerm),
|
(unix::SignalKind::terminate(), SignalKind::Term),
|
||||||
(unix::SignalKind::quit(), SignalKind::OsQuit),
|
(unix::SignalKind::quit(), SignalKind::Quit),
|
||||||
];
|
];
|
||||||
|
|
||||||
let signals = sig_map
|
let signals = sig_map
|
||||||
|
@ -103,18 +79,18 @@ impl OsSignals {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
OsSignals { signals }
|
Signals { signals }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Future for OsSignals {
|
impl Future for Signals {
|
||||||
type Output = SignalKind;
|
type Output = SignalKind;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
{
|
{
|
||||||
self.signals.as_mut().poll(cx).map(|_| SignalKind::OsInt)
|
self.signals.as_mut().poll(cx).map(|_| SignalKind::Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
@ -130,10 +106,3 @@ impl Future for OsSignals {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
static_assertions::assert_impl_all!(StopSignal: Send, Unpin);
|
|
||||||
}
|
|
||||||
|
|
|
@ -341,10 +341,11 @@ impl ServerWorker {
|
||||||
Ok((token, svc)) => services.push((idx, token, svc)),
|
Ok((token, svc)) => services.push((idx, token, svc)),
|
||||||
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("can not start worker: {err:?}");
|
error!("can not start worker: {:?}", err);
|
||||||
return Err(io::Error::other(format!(
|
return Err(io::Error::new(
|
||||||
"can not start server service {idx}",
|
io::ErrorKind::Other,
|
||||||
)));
|
format!("can not start server service {}", idx),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -439,12 +440,13 @@ impl ServerWorker {
|
||||||
Ok((token, svc)) => services.push((idx, token, svc)),
|
Ok((token, svc)) => services.push((idx, token, svc)),
|
||||||
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("can not start worker: {err:?}");
|
error!("can not start worker: {:?}", err);
|
||||||
Arbiter::current().stop();
|
Arbiter::current().stop();
|
||||||
factory_tx
|
factory_tx
|
||||||
.send(Err(io::Error::other(format!(
|
.send(Err(io::Error::new(
|
||||||
"can not start server service {idx}",
|
io::ErrorKind::Other,
|
||||||
))))
|
format!("can not start server service {}", idx),
|
||||||
|
)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! When MSRV is 1.82, replace with `core::future::Ready` and `core::future::ready()`.
|
//! When MSRV is 1.48, replace with `core::future::Ready` and `core::future::ready()`.
|
||||||
|
|
||||||
use core::{
|
use core::{
|
||||||
future::Future,
|
future::Future,
|
||||||
|
|
36
justfile
36
justfile
|
@ -1,8 +1,6 @@
|
||||||
_list:
|
_list:
|
||||||
@just --list
|
@just --list
|
||||||
|
|
||||||
toolchain := ""
|
|
||||||
|
|
||||||
# Check project.
|
# Check project.
|
||||||
check: && clippy
|
check: && clippy
|
||||||
just --unstable --fmt --check
|
just --unstable --fmt --check
|
||||||
|
@ -23,11 +21,11 @@ fmt:
|
||||||
# Downgrade dependencies necessary to run MSRV checks/tests.
|
# Downgrade dependencies necessary to run MSRV checks/tests.
|
||||||
[private]
|
[private]
|
||||||
downgrade-for-msrv:
|
downgrade-for-msrv:
|
||||||
cargo {{ toolchain }} update -p=native-tls --precise=0.2.13 # next ver: 1.80.0
|
cargo update -p=clap --precise=4.4.18 # next ver: 1.74.0
|
||||||
cargo {{ toolchain }} update -p=idna_adapter --precise=1.2.0 # next ver: 1.82.0
|
cargo update -p=native-tls --precise=0.2.13 # next ver: 1.80.0
|
||||||
cargo {{ toolchain }} update -p=litemap --precise=0.7.4 # next ver: 1.81.0
|
cargo update -p=litemap --precise=0.7.4 # next ver: 1.81.0
|
||||||
cargo {{ toolchain }} update -p=zerofrom --precise=0.1.5 # next ver: 1.81.0
|
cargo update -p=zerofrom --precise=0.1.5 # next ver: 1.81.0
|
||||||
cargo {{ toolchain }} update -p=half --precise=2.4.1 # next ver: 1.81.0
|
cargo update -p=half --precise=2.4.1 # next ver: 1.81.0
|
||||||
|
|
||||||
msrv := ```
|
msrv := ```
|
||||||
cargo metadata --format-version=1 \
|
cargo metadata --format-version=1 \
|
||||||
|
@ -45,39 +43,37 @@ non_linux_all_features_list := ```
|
||||||
all_crate_features := if os() == "linux" { "--all-features" } else { "--features='" + non_linux_all_features_list + "'" }
|
all_crate_features := if os() == "linux" { "--all-features" } else { "--features='" + non_linux_all_features_list + "'" }
|
||||||
|
|
||||||
# Run Clippy over workspace.
|
# Run Clippy over workspace.
|
||||||
clippy:
|
clippy toolchain="":
|
||||||
cargo {{ toolchain }} clippy --workspace --all-targets {{ all_crate_features }}
|
cargo {{ toolchain }} clippy --workspace --all-targets {{ all_crate_features }}
|
||||||
|
|
||||||
# Run Clippy using MSRV.
|
# Run Clippy using MSRV.
|
||||||
clippy-msrv: downgrade-for-msrv
|
clippy-msrv: downgrade-for-msrv (clippy msrv_rustup)
|
||||||
@just toolchain={{ msrv_rustup }} clippy
|
|
||||||
|
|
||||||
# Test workspace code.
|
# Test workspace code.
|
||||||
[macos]
|
[macos]
|
||||||
[windows]
|
[windows]
|
||||||
test:
|
test toolchain="":
|
||||||
cargo {{ toolchain }} test --lib --tests --package=actix-macros
|
cargo {{ toolchain }} test --lib --tests --package=actix-macros
|
||||||
cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-macros --no-default-features
|
cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-macros --no-default-features
|
||||||
cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-macros {{ all_crate_features }}
|
cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-macros {{ all_crate_features }}
|
||||||
|
|
||||||
# Test workspace code.
|
# Test workspace code.
|
||||||
[linux]
|
[linux]
|
||||||
test:
|
test toolchain="":
|
||||||
cargo {{ toolchain }} test --lib --tests --package=actix-macros
|
cargo {{ toolchain }} test --lib --tests --package=actix-macros
|
||||||
cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-macros --no-default-features
|
cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-macros --no-default-features
|
||||||
cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-macros {{ non_linux_all_features_list }}
|
cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-macros {{ non_linux_all_features_list }}
|
||||||
cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-macros {{ all_crate_features }}
|
cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-macros {{ all_crate_features }}
|
||||||
|
|
||||||
# Test workspace using MSRV.
|
# Test workspace using MSRV.
|
||||||
test-msrv: downgrade-for-msrv
|
test-msrv: downgrade-for-msrv (test msrv_rustup)
|
||||||
@just toolchain={{ msrv_rustup }} test
|
|
||||||
|
|
||||||
# Test workspace docs.
|
# Test workspace docs.
|
||||||
test-docs: && doc
|
test-docs toolchain="": && doc
|
||||||
cargo {{ toolchain }} test --doc --workspace {{ all_crate_features }} --no-fail-fast -- --nocapture
|
cargo {{ toolchain }} test --doc --workspace {{ all_crate_features }} --no-fail-fast -- --nocapture
|
||||||
|
|
||||||
# Test workspace.
|
# Test workspace.
|
||||||
test-all: test test-docs
|
test-all toolchain="": (test toolchain) (test-docs toolchain)
|
||||||
|
|
||||||
# Document crates in workspace.
|
# Document crates in workspace.
|
||||||
doc *args: && doc-set-workspace-crates
|
doc *args: && doc-set-workspace-crates
|
||||||
|
@ -100,12 +96,12 @@ doc-watch:
|
||||||
cargo watch -- just doc
|
cargo watch -- just doc
|
||||||
|
|
||||||
# Check for unintentional external type exposure on all crates in workspace.
|
# Check for unintentional external type exposure on all crates in workspace.
|
||||||
check-external-types-all:
|
check-external-types-all toolchain="+nightly":
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
exit=0
|
exit=0
|
||||||
for f in $(find . -mindepth 2 -maxdepth 2 -name Cargo.toml | grep -vE "\-codegen/|\-derive/|\-macros/"); do
|
for f in $(find . -mindepth 2 -maxdepth 2 -name Cargo.toml | grep -vE "\-codegen/|\-derive/|\-macros/"); do
|
||||||
if ! just toolchain="+nightly" check-external-types-manifest "$f"; then exit=1; fi
|
if ! just check-external-types-manifest "$f" {{ toolchain }}; then exit=1; fi
|
||||||
echo
|
echo
|
||||||
echo
|
echo
|
||||||
done
|
done
|
||||||
|
@ -118,9 +114,9 @@ check-external-types-all-table toolchain="+nightly":
|
||||||
for f in $(find . -mindepth 2 -maxdepth 2 -name Cargo.toml | grep -vE "\-codegen/|\-derive/|\-macros/"); do
|
for f in $(find . -mindepth 2 -maxdepth 2 -name Cargo.toml | grep -vE "\-codegen/|\-derive/|\-macros/"); do
|
||||||
echo
|
echo
|
||||||
echo "Checking for $f"
|
echo "Checking for $f"
|
||||||
just toolchain="+nightly" check-external-types-manifest "$f" --output-format=markdown-table
|
just check-external-types-manifest "$f" {{ toolchain }} --output-format=markdown-table
|
||||||
done
|
done
|
||||||
|
|
||||||
# Check for unintentional external type exposure on a crate.
|
# Check for unintentional external type exposure on a crate.
|
||||||
check-external-types-manifest manifest_path *extra_args="":
|
check-external-types-manifest manifest_path toolchain="+nightly" *extra_args="":
|
||||||
cargo {{ toolchain }} check-external-types --manifest-path "{{ manifest_path }}" {{ extra_args }}
|
cargo {{ toolchain }} check-external-types --manifest-path "{{ manifest_path }}" {{ extra_args }}
|
||||||
|
|
Loading…
Reference in New Issue