1
0
mirror of https://github.com/fafhrd91/actix-net synced 2025-08-13 11:58:23 +02:00

Compare commits

...

17 Commits

Author SHA1 Message Date
Rob Ede
8666c4063f temp 2020-12-23 19:44:54 +00:00
Yuki Okushi
4e4122b702 Disable PR comment from codecov 2020-12-17 21:42:21 +09:00
Aravinth Manivannan
b296d0f254 Intradoc links conversion (#227)
* intra doc conversion

* rm trailing blank comment
2020-12-14 08:22:30 +00:00
Juan Aguilar
02a902068f Refactor LocalWaker (#224) 2020-12-13 19:26:57 +00:00
fakeshadow
049795662f remove ServerMessage type. remove one unused InternalServiceFactory impl (#225) 2020-12-13 00:46:32 +00:00
Rob Ede
4e43216b99 standardise compiler lints across all crates (#226) 2020-12-12 23:24:00 +00:00
Rob Ede
93889776c4 prevent double registration of sockets when backpressure is resolved (#223) 2020-12-12 17:19:20 +00:00
Yuki Okushi
ab496a71b5 Fix release date 2020-12-03 08:59:59 +09:00
Yuki Okushi
76d956e25c macros: Add actix-reexport feature (#218) 2020-12-03 08:59:13 +09:00
Ivan Babrou
89e56cf661 Notify about paused accept loop (#215) 2020-11-29 15:30:13 +00:00
Rob Ede
8aca8d4d07 fix clippy warnings (#214)
and make my spelling checker happy
2020-11-25 01:41:14 +00:00
fakeshadow
e0dd2a3d76 remove actix-threadpool re-export from actix-rt (#212) 2020-11-24 17:03:09 +00:00
Rob Ede
59e976aaca address clippy error (#213) 2020-11-24 16:35:47 +00:00
Zura Benashvili
4cc1c87724 docs(transform): remove extra generic parameter (#211) 2020-11-20 22:45:57 +00:00
Yuki Okushi
ca39917d2c Update CoC contact information 2020-10-31 12:08:06 +09:00
ghizzo01
704af672b9 Bump pin-project to 1.0 (#202) 2020-10-25 19:42:40 +09:00
Rob Ede
242bef269f delete ioframe removed package readme
closes #199
2020-09-22 12:29:07 +01:00
51 changed files with 342 additions and 195 deletions

View File

@@ -31,4 +31,4 @@ jobs:
uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features --all --tests
args: --workspace --tests

View File

@@ -53,20 +53,20 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: check
args: --all --bins --examples --tests
args: --workspace --bins --examples --tests
- name: tests
uses: actions-rs/cargo@v1
timeout-minutes: 40
with:
command: test
args: --all --all-features --no-fail-fast -- --nocapture
args: --workspace --exclude=actix-tls --no-fail-fast -- --nocapture
- name: Generate coverage file
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
run: |
cargo install cargo-tarpaulin
cargo tarpaulin --out Xml --workspace --all-features
cargo tarpaulin --out Xml --workspace
- name: Upload to Codecov
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')

View File

@@ -34,10 +34,10 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: check
args: --all --bins --examples --tests
args: --workspace --bins --examples --tests
- name: tests
uses: actions-rs/cargo@v1
with:
command: test
args: --all --all-features --no-fail-fast -- --nocapture
args: --workspace --exclude=actix-tls --no-fail-fast -- --nocapture

View File

@@ -42,4 +42,4 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: check
args: --all --bins --examples --tests
args: --workspace --bins --examples --tests

View File

@@ -60,10 +60,10 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: check
args: --all --bins --examples --tests
args: --workspace --bins --examples --tests
- name: tests
uses: actions-rs/cargo@v1
with:
command: test
args: --all --all-features --no-fail-fast -- --nocapture
args: --workspace --exclude=actix-tls --no-fail-fast -- --nocapture

View File

@@ -34,10 +34,13 @@ This Code of Conduct applies both within project spaces and in public spaces whe
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at fafhrd91@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at robjtede@icloud.com ([@robjtede]) or huyuumi@neet.club ([@JohnTitor]). The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
[@robjtede]: https://github.com/robjtede
[@JohnTitor]: https://github.com/JohnTitor
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]

View File

@@ -1,6 +1,7 @@
# Changes
## Unreleased - 2020-xx-xx
* Upgrade `pin-project` to `1.0`.
## 0.3.0 - 2020-08-23
* No changes from beta 2.

View File

@@ -21,6 +21,6 @@ bytes = "0.5.2"
futures-core = { version = "0.3.4", default-features = false }
futures-sink = { version = "0.3.4", default-features = false }
log = "0.4"
pin-project = "0.4.17"
pin-project = "1.0.0"
tokio = { version = "0.2.5", default-features = false }
tokio-util = { version = "0.3.1", default-features = false, features = ["codec"] }

View File

@@ -4,13 +4,13 @@
//! [`AsyncWrite`], to framed streams implementing [`Sink`] and [`Stream`].
//! Framed streams are also known as `transports`.
//!
//! [`AsyncRead`]: AsyncRead
//! [`AsyncWrite`]: AsyncWrite
//! [`Sink`]: futures_sink::Sink
//! [`Stream`]: futures_core::Stream
#![deny(rust_2018_idioms)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(missing_docs)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
mod bcodec;
mod framed;

View File

@@ -138,7 +138,7 @@ impl<T: Address> fmt::Display for Connect<T> {
}
}
/// Iterator over addresses in a [`Connect`](struct.Connect.html) request.
/// Iterator over addresses in a [`Connect`] request.
#[derive(Clone)]
pub struct ConnectAddrsIter<'a> {
inner: Either<Option<SocketAddr>, vec_deque::Iter<'a, SocketAddr>>,
@@ -173,7 +173,7 @@ impl ExactSizeIterator for ConnectAddrsIter<'_> {}
impl FusedIterator for ConnectAddrsIter<'_> {}
/// Owned iterator over addresses in a [`Connect`](struct.Connect.html) request.
/// Owned iterator over addresses in a [`Connect`] request.
#[derive(Debug)]
pub struct ConnectTakeAddrsIter {
inner: Either<Option<SocketAddr>, vec_deque::IntoIter<SocketAddr>>,

View File

@@ -5,8 +5,10 @@
//! * `openssl` - enables TLS support via `openssl` crate
//! * `rustls` - enables TLS support via `rustls` crate
#![deny(rust_2018_idioms)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![recursion_limit = "128"]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
#[macro_use]
extern crate log;

View File

@@ -1,3 +0,0 @@
# actix-ioframe
**This crate has been deprecated and removed.**

View File

@@ -1,5 +1,9 @@
# CHANGES
## 0.1.3 - 2020-12-3
* Add `actix-reexport` feature
## 0.1.2 - 2020-05-18
### Changed

View File

@@ -1,6 +1,6 @@
[package]
name = "actix-macros"
version = "0.1.2"
version = "0.1.3"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Actix runtime macros"
repository = "https://github.com/actix/actix-net"
@@ -16,6 +16,9 @@ proc-macro = true
quote = "1.0.3"
syn = { version = "^1", features = ["full"] }
[features]
actix-reexport = []
[dev-dependencies]
actix-rt = "1.0"

View File

@@ -1,5 +1,8 @@
//! Macros for use with Tokio
extern crate proc_macro;
#![deny(rust_2018_idioms, nonstandard_style)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
use proc_macro::TokenStream;
use quote::quote;
@@ -33,14 +36,25 @@ pub fn main(_: TokenStream, item: TokenStream) -> TokenStream {
sig.asyncness = None;
(quote! {
#(#attrs)*
#vis #sig {
actix_rt::System::new(stringify!(#name))
.block_on(async move { #body })
}
})
.into()
if cfg!(feature = "actix-reexport") {
(quote! {
#(#attrs)*
#vis #sig {
actix::System::new(stringify!(#name))
.block_on(async move { #body })
}
})
.into()
} else {
(quote! {
#(#attrs)*
#vis #sig {
actix_rt::System::new(stringify!(#name))
.block_on(async move { #body })
}
})
.into()
}
}
/// Marks async test function to be executed by actix runtime.

View File

@@ -17,10 +17,9 @@ path = "src/lib.rs"
[dependencies]
actix-macros = "0.1.0"
actix-threadpool = "0.3"
futures-channel = { version = "0.3.4", default-features = false }
futures-util = { version = "0.3.4", default-features = false, features = ["alloc"] }
copyless = "0.1.4"
futures-channel = "0.3.4"
futures-util = { version = "0.3.4", default-features = false, features = ["alloc"] }
smallvec = "1"
tokio = { version = "0.2.6", default-features = false, features = ["rt-core", "rt-util", "io-driver", "tcp", "uds", "udp", "time", "signal", "stream"] }

View File

@@ -134,10 +134,7 @@ impl Arbiter {
.unbounded_send(SystemCommand::RegisterArbiter(id, arb));
// run loop
let _ = match rt.block_on(stop_rx) {
Ok(code) => code,
Err(_) => 1,
};
let _ = rt.block_on(stop_rx).unwrap_or(1);
// unregister arbiter
let _ = System::current()
@@ -336,7 +333,7 @@ impl Future for CleanupPending {
let mut pending = cell.borrow_mut();
let mut i = 0;
while i != pending.len() {
if let Poll::Ready(_) = Pin::new(&mut pending[i]).poll(cx) {
if Pin::new(&mut pending[i]).poll(cx).is_ready() {
pending.remove(i);
} else {
i += 1;

View File

@@ -1,6 +1,8 @@
//! A runtime implementation that runs everything on the current thread.
#![deny(rust_2018_idioms, warnings)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![allow(clippy::type_complexity)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
#[cfg(not(test))] // Work around for rust-lang/rust#62127
pub use actix_macros::{main, test};
@@ -15,9 +17,6 @@ pub use self::builder::{Builder, SystemRunner};
pub use self::runtime::Runtime;
pub use self::system::System;
#[doc(hidden)]
pub use actix_threadpool as blocking;
/// Spawns a future on the current arbiter.
///
/// # Panics

View File

@@ -7,7 +7,7 @@ use tokio::{runtime, task::LocalSet};
///
/// See [module level][mod] documentation for more details.
///
/// [mod]: index.html
/// [mod]: crate
#[derive(Debug)]
pub struct Runtime {
local: LocalSet,
@@ -34,7 +34,7 @@ impl Runtime {
///
/// See [module level][mod] documentation for more details.
///
/// [mod]: index.html
/// [mod]: crate
///
/// # Examples
///

View File

@@ -66,7 +66,6 @@ impl System {
/// It means that using this method currently it is impossible to make `actix-rt` work in the
/// alternative `tokio` `Runtime`s (e.g. provided by [`tokio_compat`]).
///
/// [`Arbiter`]: struct.Arbiter.html
/// [`tokio_compat`]: https://crates.io/crates/tokio-compat
///
/// # Examples
@@ -131,7 +130,6 @@ impl System {
/// It means that using this method currently it is impossible to make `actix-rt` work in the
/// alternative `tokio` `Runtime`s (e.g. provided by `tokio_compat`).
///
/// [`Arbiter`]: struct.Arbiter.html
/// [`tokio_compat`]: https://crates.io/crates/tokio-compat
///
/// # Arguments

View File

@@ -1,6 +1,11 @@
# Changes
## Unreleased - 2020-xx-xx
* Added explicit info log message on accept queue pause. [#215]
* Prevent double registration of sockets when back-pressure is resolved. [#223]
[#215]: https://github.com/actix/actix-net/pull/215
[#223]: https://github.com/actix/actix-net/pull/223
## 1.0.4 - 2020-09-12

View File

@@ -370,6 +370,11 @@ impl Accept {
if !on {
self.backpressure = false;
for (token, info) in self.sockets.iter() {
if info.timeout.is_some() {
// socket will attempt to re-register itself when its timeout completes
continue;
}
if let Err(err) = self.register(token, info) {
error!("Can not resume socket accept process: {}", err);
} else {
@@ -381,6 +386,7 @@ impl Accept {
self.backpressure = true;
for (_, info) in self.sockets.iter() {
let _ = self.poll.deregister(&info.sock);
info!("Accepting connections on {} has been paused", info.addr);
}
}
}

View File

@@ -286,7 +286,7 @@ impl ServerBuilder {
// handle signals
if !self.no_signals {
Signals::start(self.server.clone()).unwrap();
Signals::start(self.server.clone());
}
// start http server actor

View File

@@ -8,10 +8,9 @@ use futures_util::future::{ok, Future, FutureExt, LocalBoxFuture};
use log::error;
use super::builder::bind_addr;
use super::service::{
BoxedServerService, InternalServiceFactory, ServerMessage, StreamService,
};
use super::service::{BoxedServerService, InternalServiceFactory, StreamService};
use super::Token;
use crate::socket::StdStream;
pub struct ServiceConfig {
pub(crate) services: Vec<(String, net::TcpListener)>,
@@ -239,7 +238,7 @@ impl ServiceRuntime {
type BoxedNewService = Box<
dyn actix::ServiceFactory<
Request = (Option<CounterGuard>, ServerMessage),
Request = (Option<CounterGuard>, StdStream),
Response = (),
Error = (),
InitError = (),
@@ -261,12 +260,12 @@ where
T::Error: 'static,
T::InitError: fmt::Debug + 'static,
{
type Request = (Option<CounterGuard>, ServerMessage);
type Request = (Option<CounterGuard>, StdStream);
type Response = ();
type Error = ();
type InitError = ();
type Config = ();
type Service = BoxedServerService;
type InitError = ();
type Future = LocalBoxFuture<'static, Result<BoxedServerService, ()>>;
fn new_service(&self, _: ()) -> Self::Future {

View File

@@ -1,6 +1,8 @@
//! General purpose TCP server.
#![deny(rust_2018_idioms)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
mod accept;
mod builder;

View File

@@ -1,7 +1,6 @@
use std::marker::PhantomData;
use std::net::SocketAddr;
use std::task::{Context, Poll};
use std::time::Duration;
use actix_rt::spawn;
use actix_service::{self as actix, Service, ServiceFactory as ActixServiceFactory};
@@ -13,18 +12,6 @@ use log::error;
use super::Token;
use crate::socket::{FromStream, StdStream};
/// Server message
pub(crate) enum ServerMessage {
/// New stream
Connect(StdStream),
/// Gracefully shutdown
Shutdown(Duration),
/// Force shutdown
ForceShutdown,
}
pub trait ServiceFactory<Stream: FromStream>: Send + Clone + 'static {
type Factory: actix::ServiceFactory<Config = (), Request = Stream>;
@@ -41,7 +28,7 @@ pub(crate) trait InternalServiceFactory: Send {
pub(crate) type BoxedServerService = Box<
dyn Service<
Request = (Option<CounterGuard>, ServerMessage),
Request = (Option<CounterGuard>, StdStream),
Response = (),
Error = (),
Future = Ready<Result<(), ()>>,
@@ -65,7 +52,7 @@ where
T::Error: 'static,
I: FromStream,
{
type Request = (Option<CounterGuard>, ServerMessage);
type Request = (Option<CounterGuard>, StdStream);
type Response = ();
type Error = ();
type Future = Ready<Result<(), ()>>;
@@ -74,25 +61,20 @@ where
self.service.poll_ready(ctx).map_err(|_| ())
}
fn call(&mut self, (guard, req): (Option<CounterGuard>, ServerMessage)) -> Self::Future {
match req {
ServerMessage::Connect(stream) => {
let stream = FromStream::from_stdstream(stream).map_err(|e| {
error!("Can not convert to an async tcp stream: {}", e);
fn call(&mut self, (guard, req): (Option<CounterGuard>, StdStream)) -> Self::Future {
match FromStream::from_stdstream(req) {
Ok(stream) => {
let f = self.service.call(stream);
spawn(async move {
let _ = f.await;
drop(guard);
});
if let Ok(stream) = stream {
let f = self.service.call(stream);
spawn(async move {
let _ = f.await;
drop(guard);
});
ok(())
} else {
err(())
}
ok(())
}
Err(e) => {
error!("Can not convert to an async tcp stream: {}", e);
err(())
}
_ => ok(()),
}
}
}
@@ -159,20 +141,6 @@ where
}
}
impl InternalServiceFactory for Box<dyn InternalServiceFactory> {
fn name(&self, token: Token) -> &str {
self.as_ref().name(token)
}
fn clone_factory(&self) -> Box<dyn InternalServiceFactory> {
self.as_ref().clone_factory()
}
fn create(&self) -> LocalBoxFuture<'static, Result<Vec<(Token, BoxedServerService)>, ()>> {
self.as_ref().create()
}
}
impl<F, T, I> ServiceFactory<I> for F
where
F: Fn() -> T + Send + Clone + 'static,

View File

@@ -1,5 +1,4 @@
use std::future::Future;
use std::io;
use std::pin::Pin;
use std::task::{Context, Poll};
@@ -24,13 +23,13 @@ pub(crate) enum Signal {
pub(crate) struct Signals {
srv: Server,
#[cfg(not(unix))]
stream: Pin<Box<dyn Future<Output = io::Result<()>>>>,
stream: Pin<Box<dyn Future<Output = std::io::Result<()>>>>,
#[cfg(unix)]
streams: Vec<(Signal, actix_rt::signal::unix::Signal)>,
}
impl Signals {
pub(crate) fn start(srv: Server) -> io::Result<()> {
pub(crate) fn start(srv: Server) {
actix_rt::spawn(lazy(|_| {
#[cfg(not(unix))]
{
@@ -66,8 +65,6 @@ impl Signals {
actix_rt::spawn(Signals { srv, streams })
}
}));
Ok(())
}
}

View File

@@ -14,7 +14,7 @@ use futures_util::{future::Future, stream::Stream, FutureExt, TryFutureExt};
use log::{error, info, trace};
use crate::accept::AcceptNotify;
use crate::service::{BoxedServerService, InternalServiceFactory, ServerMessage};
use crate::service::{BoxedServerService, InternalServiceFactory};
use crate::socket::{SocketAddr, StdStream};
use crate::Token;
@@ -228,23 +228,12 @@ impl Worker {
self.services.iter_mut().for_each(|srv| {
if srv.status == WorkerServiceStatus::Available {
srv.status = WorkerServiceStatus::Stopped;
actix_rt::spawn(
srv.service
.call((None, ServerMessage::ForceShutdown))
.map(|_| ()),
);
}
});
} else {
let timeout = self.shutdown_timeout;
self.services.iter_mut().for_each(move |srv| {
if srv.status == WorkerServiceStatus::Available {
srv.status = WorkerServiceStatus::Stopping;
actix_rt::spawn(
srv.service
.call((None, ServerMessage::Shutdown(timeout)))
.map(|_| ()),
);
}
});
}
@@ -361,7 +350,7 @@ impl Future for Worker {
let guard = self.conns.get();
let _ = self.services[conn.token.0]
.service
.call((Some(guard), ServerMessage::Connect(conn.io)));
.call((Some(guard), conn.io));
} else {
self.state = WorkerState::Available;
self.availability.set(true);
@@ -455,7 +444,7 @@ impl Future for Worker {
let guard = self.conns.get();
let _ = self.services[msg.token.0]
.service
.call((Some(guard), ServerMessage::Connect(msg.io)));
.call((Some(guard), msg.io));
continue;
}
Ok(false) => {

View File

@@ -1,7 +1,7 @@
# Changes
## Unreleased - 2020-xx-xx
* Upgrade `pin-project` to `1.0`.
## 1.0.6 - 2020-08-09

View File

@@ -18,7 +18,7 @@ path = "src/lib.rs"
[dependencies]
futures-util = "0.3.1"
pin-project = "0.4.17"
pin-project = "1.0.0"
[dev-dependencies]
actix-rt = "1.0.0"

View File

@@ -1,7 +1,9 @@
//! See [`Service`](trait.Service.html) docs for information on this crate's foundational trait.
//! See [`Service`] docs for information on this crate's foundational trait.
#![deny(rust_2018_idioms, warnings)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![allow(clippy::type_complexity)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
use std::cell::RefCell;
use std::future::Future;
@@ -65,7 +67,7 @@ pub use self::transform::{apply, Transform};
/// ```
///
/// Sometimes it is not necessary to implement the Service trait. For example, the above service
/// could be rewritten as a simple function and passed to [fn_service](fn.fn_service.html).
/// could be rewritten as a simple function and passed to [fn_service](fn_service()).
///
/// ```rust,ignore
/// async fn my_service(req: u8) -> Result<u64, MyError>;

View File

@@ -70,7 +70,7 @@ where
/// timeout: Duration,
/// }
///
/// impl<S> Transform<S> for TimeoutTransform<E>
/// impl<S> Transform<S> for TimeoutTransform
/// where
/// S: Service,
/// {

View File

@@ -1,6 +1,9 @@
//! Various helpers for Actix applications to use during testing.
#![deny(rust_2018_idioms, warnings)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![allow(clippy::type_complexity, clippy::needless_doctest_main)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
use std::sync::mpsc;
use std::{net, thread};

View File

@@ -1,5 +1,9 @@
//! Thread pool for blocking operations
#![deny(rust_2018_idioms, nonstandard_style)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
use std::fmt;
use std::future::Future;
use std::pin::Pin;

View File

@@ -5,7 +5,9 @@
//! * `rustls` - TLS acceptor using the `rustls` crate.
//! * `nativetls` - TLS acceptor using the `native-tls` crate.
#![deny(rust_2018_idioms)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
use std::sync::atomic::{AtomicUsize, Ordering};

View File

@@ -1,5 +1,8 @@
//! Actix tracing - support for tokio tracing with Actix services.
#![deny(rust_2018_idioms, warnings)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
use std::marker::PhantomData;
use std::task::{Context, Poll};
@@ -57,8 +60,6 @@ where
}
/// A `Transform` implementation that wraps services with a [`TracingService`].
///
/// [`TracingService`]: struct.TracingService.html
pub struct TracingTransform<S, U, F> {
make_span: F,
_p: PhantomData<fn(S, U)>,

View File

@@ -1,6 +1,7 @@
# Changes
## Unreleased - 2020-xx-xx
* Upgrade `pin-project` to `1.0`.
## 2.0.0 - 2020-08-23
* No changes from beta 1.

View File

@@ -26,5 +26,5 @@ futures-channel = { version = "0.3.4", default-features = false }
futures-sink = { version = "0.3.4", default-features = false }
futures-util = { version = "0.3.4", default-features = false }
log = "0.4"
pin-project = "0.4.17"
pin-project = "1.0.0"
slab = "0.4"

View File

@@ -290,10 +290,8 @@ where
}
State::Error(_) => {
// flush write buffer
if !this.framed.is_write_buf_empty() {
if let Poll::Pending = this.framed.flush(cx) {
return Poll::Pending;
}
if !this.framed.is_write_buf_empty() && this.framed.flush(cx).is_pending() {
return Poll::Pending;
}
Poll::Ready(Err(this.state.take_error()))
}

View File

@@ -74,7 +74,7 @@ where
type Future = InFlightServiceResponse<T>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
if let Poll::Pending = self.service.poll_ready(cx)? {
if self.service.poll_ready(cx)?.is_pending() {
Poll::Pending
} else if !self.count.available(cx) {
log::trace!("InFlight limit exceeded");

View File

@@ -1,7 +1,9 @@
//! Actix utils - various helper services
#![deny(rust_2018_idioms)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![allow(clippy::type_complexity)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
pub mod condition;
pub mod counter;

View File

@@ -160,7 +160,12 @@ where
}
// check nested service
if let Poll::Pending = self.service.poll_ready(cx).map_err(InOrderError::Service)? {
if self
.service
.poll_ready(cx)
.map_err(InOrderError::Service)?
.is_pending()
{
Poll::Pending
} else {
Poll::Ready(Ok(()))

View File

@@ -19,6 +19,7 @@ use std::{fmt, rc};
///
/// A single `AtomicWaker` may be reused for any number of calls to `register` or
/// `wake`.
// TODO: Refactor to Cell when remove deprecated methods (@botika)
#[derive(Default)]
pub struct LocalWaker {
pub(crate) waker: UnsafeCell<Option<Waker>>,
@@ -34,6 +35,10 @@ impl LocalWaker {
}
}
#[deprecated(
since = "2.1.0",
note = "In favor of `wake`. State of the register doesn't matter at `wake` up"
)]
#[inline]
/// Check if waker has been registered.
pub fn is_registered(&self) -> bool {
@@ -47,9 +52,8 @@ impl LocalWaker {
pub fn register(&self, waker: &Waker) -> bool {
unsafe {
let w = self.waker.get();
let is_registered = (*w).is_some();
*w = Some(waker.clone());
is_registered
let last_waker = w.replace(Some(waker.clone()));
last_waker.is_some()
}
}
@@ -63,6 +67,7 @@ impl LocalWaker {
}
}
#[inline]
/// Returns the last `Waker` passed to `register`, so that the user can wake it.
///
/// If a waker has not been registered, this returns `None`.

View File

@@ -1,3 +1,5 @@
comment: false
coverage:
status:
project:

View File

@@ -1,3 +1,5 @@
use std::fmt;
use serde::de::{self, Deserializer, Error as DeError, Visitor};
use serde::forward_to_deserialize_any;
@@ -42,17 +44,24 @@ macro_rules! parse_single_value {
};
}
pub struct PathDeserializer<'de, T: ResourcePath + 'de> {
#[derive(Debug)]
pub struct PathDeserializer<'de, T: ResourcePath + fmt::Debug> {
path: &'de Path<T>,
}
impl<'de, T: ResourcePath + 'de> PathDeserializer<'de, T> {
impl<'de, T> PathDeserializer<'de, T>
where
T: ResourcePath + fmt::Debug + 'de,
{
pub fn new(path: &'de Path<T>) -> Self {
PathDeserializer { path }
}
}
impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T> {
impl<'de, T> Deserializer<'de> for PathDeserializer<'de, T>
where
T: ResourcePath + fmt::Debug + 'de,
{
type Error = de::value::Error;
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@@ -103,6 +112,7 @@ impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T>
where
V: Visitor<'de>,
{
eprintln!("heres my newtype");
visitor.visit_newtype_struct(self)
}
@@ -154,15 +164,19 @@ impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T>
fn deserialize_enum<V>(
self,
_: &'static str,
_: &'static [&'static str],
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
eprintln!("variants: {:?}", &variants);
if self.path.is_empty() {
Err(de::value::Error::custom("expected at least one parameters"))
} else {
eprintln!("{:?}", &self.path[0]);
visitor.visit_enum(ValueEnum {
value: &self.path[0],
})
@@ -191,7 +205,16 @@ impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T>
})
}
unsupported_type!(deserialize_any, "'any'");
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.path[0].parse::<u64>() {
Ok(int) => visitor.visit_u64(int),
Err(_) => visitor.visit_str(&self.path[0]),
}
}
unsupported_type!(deserialize_bytes, "bytes");
unsupported_type!(deserialize_option, "Option<T>");
unsupported_type!(deserialize_identifier, "identifier");
@@ -218,7 +241,10 @@ struct ParamsDeserializer<'de, T: ResourcePath> {
current: Option<(&'de str, &'de str)>,
}
impl<'de, T: ResourcePath> de::MapAccess<'de> for ParamsDeserializer<'de, T> {
impl<'de, T> de::MapAccess<'de> for ParamsDeserializer<'de, T>
where
T: ResourcePath + fmt::Debug,
{
type Error = de::value::Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
@@ -262,6 +288,7 @@ impl<'de> Deserializer<'de> for Key<'de> {
where
V: Visitor<'de>,
{
eprintln!("Key::deserialize_any");
Err(de::value::Error::custom("Unexpected"))
}
@@ -312,6 +339,7 @@ impl<'de> Deserializer<'de> for Value<'de> {
where
V: Visitor<'de>,
{
eprintln!("Value::deserialize_ignored_any");
visitor.visit_unit()
}
@@ -418,7 +446,10 @@ struct ParamsSeq<'de, T: ResourcePath> {
params: PathIter<'de, T>,
}
impl<'de, T: ResourcePath> de::SeqAccess<'de> for ParamsSeq<'de, T> {
impl<'de, T> de::SeqAccess<'de> for ParamsSeq<'de, T>
where
T: ResourcePath + fmt::Debug,
{
type Error = de::value::Error;
fn next_element_seed<U>(&mut self, seed: U) -> Result<Option<U::Value>, Self::Error>
@@ -432,8 +463,10 @@ impl<'de, T: ResourcePath> de::SeqAccess<'de> for ParamsSeq<'de, T> {
}
}
#[derive(Debug)]
struct ValueEnum<'de> {
value: &'de str,
// todo there maybe must be some state here to decide on which variant to use
}
impl<'de> de::EnumAccess<'de> for ValueEnum<'de> {
@@ -444,6 +477,9 @@ impl<'de> de::EnumAccess<'de> for ValueEnum<'de> {
where
V: de::DeserializeSeed<'de>,
{
// eprintln!("seed: {:?}", &seed);
eprintln!("value: {:?}", &self.value);
Ok((seed.deserialize(Key { key: self.value })?, UnitVariant))
}
}
@@ -454,6 +490,7 @@ impl<'de> de::VariantAccess<'de> for UnitVariant {
type Error = de::value::Error;
fn unit_variant(self) -> Result<(), Self::Error> {
eprintln!("try unit variant");
Ok(())
}
@@ -461,6 +498,7 @@ impl<'de> de::VariantAccess<'de> for UnitVariant {
where
T: de::DeserializeSeed<'de>,
{
eprintln!("try newtype variant");
Err(de::value::Error::custom("not supported"))
}
@@ -468,6 +506,7 @@ impl<'de> de::VariantAccess<'de> for UnitVariant {
where
V: Visitor<'de>,
{
eprintln!("try tuple variant");
Err(de::value::Error::custom("not supported"))
}
@@ -479,6 +518,7 @@ impl<'de> de::VariantAccess<'de> for UnitVariant {
where
V: Visitor<'de>,
{
eprintln!("try struct variant");
Err(de::value::Error::custom("not supported"))
}
}
@@ -512,6 +552,11 @@ mod tests {
value: u32,
}
#[derive(Debug, Deserialize)]
struct Test3 {
val: TestEnum,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
enum TestEnum {
@@ -519,9 +564,72 @@ mod tests {
Val2,
}
#[derive(Debug, Deserialize)]
struct Test3 {
val: TestEnum,
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum TestEnum2 {
Int(u32),
String(String),
}
#[allow(non_snake_case)]
mod __TestEnum2 {
use std::fmt;
use serde::{
export::{Err as SErr, Ok as SOk, Result as SResult},
private::de::{Content, ContentRefDeserializer},
Deserialize,
};
use super::TestEnum2;
impl<'de> serde::Deserialize<'de> for TestEnum2 {
fn deserialize<D>(deserializer: D) -> SResult<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
eprintln!(
"!!derive!! deserializer: {:?}",
&deserializer.is_human_readable()
);
let content = match <Content<'_> as Deserialize>::deserialize(deserializer) {
SOk(val) => {
eprintln!("!!derive!! content val: {:?}", &val);
val
}
SErr(err) => {
eprintln!("!!derive!! content err: {:?}", &err);
return SErr(err);
}
};
let cnt1 = ContentRefDeserializer::<D::Error>::new(&content);
let de1 = <u32 as Deserialize>::deserialize(cnt1);
// eprintln!("!!derive!! cnt1: {:?}", &cnt1);
eprintln!("!!derive!! de1: {:?}", &de1);
if let SOk(ok) = SResult::map(de1, TestEnum2::Int) {
eprintln!("!!derive!! de1 map ok: {:?}", &ok);
return SOk(ok);
}
let cnt2 = ContentRefDeserializer::<D::Error>::new(&content);
let de2 = <String as Deserialize>::deserialize(cnt2);
// eprintln!("!!derive!! cnt2: {:?}", &cnt2);
eprintln!("!!derive!! de2: {:?}", &de2);
if let SOk(ok) = SResult::map(de2, TestEnum2::String) {
eprintln!("!!derive!! de2 map ok: {:?}", &ok);
return SOk(ok);
}
SErr(serde::de::Error::custom(
"data did not match any variant of untagged enum TestEnum2",
))
}
}
}
#[test]
@@ -591,6 +699,16 @@ mod tests {
let i: TestEnum = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
assert_eq!(i, TestEnum::Val1);
let mut path = Path::new("/22/");
assert!(router.recognize(&mut path).is_some());
let i: TestEnum2 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
assert_eq!(i, TestEnum2::Int(22));
let mut path = Path::new("/abc/");
assert!(router.recognize(&mut path).is_some());
let i: TestEnum2 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
assert_eq!(i, TestEnum2::String("abc".to_owned()));
let mut router = Router::<()>::build();
router.path("/{val1}/{val2}/", ());
let router = router.finish();

View File

@@ -1,5 +1,9 @@
//! Resource path matching library.
#![deny(rust_2018_idioms, nonstandard_style)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
mod de;
mod path;
mod resource;

View File

@@ -1,4 +1,4 @@
use std::ops::Index;
use std::{fmt, ops::Index};
use serde::de;
@@ -41,7 +41,10 @@ impl<T: Clone> Clone for Path<T> {
}
}
impl<T: ResourcePath> Path<T> {
impl<T> Path<T>
where
T: ResourcePath + fmt::Debug,
{
pub fn new(path: T) -> Path<T> {
Path {
path,
@@ -158,7 +161,7 @@ impl<T: ResourcePath> Path<T> {
}
/// Return iterator to items in parameter container
pub fn iter(&self) -> PathIter<T> {
pub fn iter(&self) -> PathIter<'_, T> {
PathIter {
idx: 0,
params: self,
@@ -177,7 +180,10 @@ pub struct PathIter<'a, T> {
params: &'a Path<T>,
}
impl<'a, T: ResourcePath> Iterator for PathIter<'a, T> {
impl<'a, T> Iterator for PathIter<'a, T>
where
T: ResourcePath + fmt::Debug,
{
type Item = (&'a str, &'a str);
#[inline]
@@ -195,7 +201,10 @@ impl<'a, T: ResourcePath> Iterator for PathIter<'a, T> {
}
}
impl<'a, T: ResourcePath> Index<&'a str> for Path<T> {
impl<'a, T> Index<&'a str> for Path<T>
where
T: ResourcePath + fmt::Debug,
{
type Output = str;
fn index(&self, name: &'a str) -> &str {

View File

@@ -1,6 +1,6 @@
use std::cmp::min;
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::{cmp::min, fmt};
use regex::{escape, Regex, RegexSet};
@@ -167,13 +167,13 @@ impl ResourceDef {
/// Is prefix path a match against this resource.
pub fn is_prefix_match(&self, path: &str) -> Option<usize> {
let plen = path.len();
let p_len = path.len();
let path = if path.is_empty() { "/" } else { path };
match self.tp {
PatternType::Static(ref s) => {
if s == path {
Some(plen)
Some(p_len)
} else {
None
}
@@ -211,7 +211,7 @@ impl ResourceDef {
} else {
return None;
};
Some(min(plen, len))
Some(min(p_len, len))
}
PatternType::DynamicSet(ref re, ref params) => {
if let Some(idx) = re.matches(path).into_iter().next() {
@@ -241,7 +241,7 @@ impl ResourceDef {
}
/// Is the given path and parameters a match against this pattern.
pub fn match_path<T: ResourcePath>(&self, path: &mut Path<T>) -> bool {
pub fn match_path<T: ResourcePath + fmt::Debug>(&self, path: &mut Path<T>) -> bool {
match self.tp {
PatternType::Static(ref s) => {
if s == path.path() {
@@ -252,11 +252,11 @@ impl ResourceDef {
}
}
PatternType::Prefix(ref s) => {
let rpath = path.path();
let len = if s == rpath {
let r_path = path.path();
let len = if s == r_path {
s.len()
} else if rpath.starts_with(s)
&& (s.ends_with('/') || rpath.split_at(s.len()).1.starts_with('/'))
} else if r_path.starts_with(s)
&& (s.ends_with('/') || r_path.split_at(s.len()).1.starts_with('/'))
{
if s.ends_with('/') {
s.len() - 1
@@ -266,8 +266,8 @@ impl ResourceDef {
} else {
return false;
};
let rpath_len = rpath.len();
path.skip(min(rpath_len, len) as u16);
let r_path_len = r_path.len();
path.skip(min(r_path_len, len) as u16);
true
}
PatternType::Dynamic(ref re, ref names, len) => {
@@ -345,7 +345,7 @@ impl ResourceDef {
user_data: &Option<U>,
) -> bool
where
T: ResourcePath,
T: ResourcePath + fmt::Debug,
R: Resource<T>,
F: Fn(&R, &Option<U>) -> bool,
{
@@ -361,11 +361,11 @@ impl ResourceDef {
}
PatternType::Prefix(ref s) => {
let len = {
let rpath = res.resource_path().path();
if s == rpath {
let r_path = res.resource_path().path();
if s == r_path {
s.len()
} else if rpath.starts_with(s)
&& (s.ends_with('/') || rpath.split_at(s.len()).1.starts_with('/'))
} else if r_path.starts_with(s)
&& (s.ends_with('/') || r_path.split_at(s.len()).1.starts_with('/'))
{
if s.ends_with('/') {
s.len() - 1
@@ -580,6 +580,8 @@ impl ResourceDef {
mut for_prefix: bool,
) -> (String, Vec<PatternElement>, bool, usize) {
if pattern.find('{').is_none() {
// TODO: MSRV: 1.45
#[allow(clippy::manual_strip)]
return if pattern.ends_with('*') {
let path = &pattern[..pattern.len() - 1];
let re = String::from("^") + path + "(.*)";
@@ -594,39 +596,39 @@ impl ResourceDef {
};
}
let mut elems = Vec::new();
let mut elements = Vec::new();
let mut re = String::from("^");
let mut dyn_elems = 0;
let mut dyn_elements = 0;
while let Some(idx) = pattern.find('{') {
let (prefix, rem) = pattern.split_at(idx);
elems.push(PatternElement::Str(String::from(prefix)));
elements.push(PatternElement::Str(String::from(prefix)));
re.push_str(&escape(prefix));
let (param_pattern, re_part, rem, tail) = Self::parse_param(rem);
if tail {
for_prefix = true;
}
elems.push(param_pattern);
elements.push(param_pattern);
re.push_str(&re_part);
pattern = rem;
dyn_elems += 1;
dyn_elements += 1;
}
elems.push(PatternElement::Str(String::from(pattern)));
elements.push(PatternElement::Str(String::from(pattern)));
re.push_str(&escape(pattern));
if dyn_elems > MAX_DYNAMIC_SEGMENTS {
if dyn_elements > MAX_DYNAMIC_SEGMENTS {
panic!(
"Only {} dynanic segments are allowed, provided: {}",
MAX_DYNAMIC_SEGMENTS, dyn_elems
"Only {} dynamic segments are allowed, provided: {}",
MAX_DYNAMIC_SEGMENTS, dyn_elements
);
}
if !for_prefix {
re.push('$');
}
(re, elems, true, pattern.chars().count())
(re, elements, true, pattern.chars().count())
}
}
@@ -718,10 +720,10 @@ mod tests {
assert!(!re.is_match("/v/resource/1"));
assert!(!re.is_match("/resource"));
let mut path = Path::new("/v151/resource/adahg32");
let mut path = Path::new("/v151/resource/adage32");
assert!(re.match_path(&mut path));
assert_eq!(path.get("version").unwrap(), "151");
assert_eq!(path.get("id").unwrap(), "adahg32");
assert_eq!(path.get("id").unwrap(), "adage32");
let re = ResourceDef::new("/{id:[[:digit:]]{6}}");
assert!(re.is_match("/012345"));
@@ -759,10 +761,10 @@ mod tests {
assert!(!re.is_match("/v/resource/1"));
assert!(!re.is_match("/resource"));
let mut path = Path::new("/v151/resource/adahg32");
let mut path = Path::new("/v151/resource/adage32");
assert!(re.match_path(&mut path));
assert_eq!(path.get("version").unwrap(), "151");
assert_eq!(path.get("id").unwrap(), "adahg32");
assert_eq!(path.get("id").unwrap(), "adage32");
assert!(re.is_match("/012345"));
assert!(!re.is_match("/012"));

View File

@@ -1,3 +1,5 @@
use std::fmt;
use crate::{IntoPattern, Resource, ResourceDef, ResourcePath};
#[derive(Debug, Copy, Clone, PartialEq)]
@@ -22,7 +24,7 @@ impl<T, U> Router<T, U> {
pub fn recognize<R, P>(&self, resource: &mut R) -> Option<(&T, ResourceId)>
where
R: Resource<P>,
P: ResourcePath,
P: ResourcePath + fmt::Debug,
{
for item in self.0.iter() {
if item.0.match_path(resource.resource_path()) {
@@ -35,7 +37,7 @@ impl<T, U> Router<T, U> {
pub fn recognize_mut<R, P>(&mut self, resource: &mut R) -> Option<(&mut T, ResourceId)>
where
R: Resource<P>,
P: ResourcePath,
P: ResourcePath + fmt::Debug,
{
for item in self.0.iter_mut() {
if item.0.match_path(resource.resource_path()) {
@@ -53,7 +55,7 @@ impl<T, U> Router<T, U> {
where
F: Fn(&R, &Option<U>) -> bool,
R: Resource<P>,
P: ResourcePath,
P: ResourcePath + fmt::Debug,
{
for item in self.0.iter_mut() {
if item.0.match_path_checked(resource, &check, &item.2) {

View File

@@ -182,11 +182,11 @@ impl Quoter {
#[inline]
fn from_hex(v: u8) -> Option<u8> {
if v >= b'0' && v <= b'9' {
if (b'0'..=b'9').contains(&v) {
Some(v - 0x30) // ord('0') == 0x30
} else if v >= b'A' && v <= b'F' {
} else if (b'A'..=b'F').contains(&v) {
Some(v - 0x41 + 10) // ord('A') == 0x41
} else if v >= b'a' && v <= b'f' {
} else if (b'a'..=b'f').contains(&v) {
Some(v - 0x61 + 10) // ord('a') == 0x61
} else {
None

View File

@@ -1,5 +1,9 @@
//! A UTF-8 encoded read-only string using Bytes as storage.
#![deny(rust_2018_idioms, nonstandard_style)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
use std::convert::TryFrom;
use std::{borrow, fmt, hash, ops, str};
@@ -7,7 +11,7 @@ use bytes::Bytes;
/// A UTF-8 encoded string with [`Bytes`] as a storage.
///
/// [`Bytes`]: https://docs.rs/bytes/0.5.3/bytes/struct.Bytes.html
/// [`Bytes`]: bytes::Bytes
#[derive(Clone, Eq, Ord, PartialOrd, Default)]
pub struct ByteString(Bytes);
@@ -156,13 +160,13 @@ macro_rules! array_impls {
array_impls!(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16);
impl fmt::Debug for ByteString {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
(**self).fmt(fmt)
}
}
impl fmt::Display for ByteString {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
(**self).fmt(fmt)
}
}