mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-23 22:51:07 +01:00
merge master
This commit is contained in:
commit
5f8599faf1
@ -23,6 +23,7 @@ members = [
|
|||||||
"actix-server-config",
|
"actix-server-config",
|
||||||
"actix-test-server",
|
"actix-test-server",
|
||||||
"actix-threadpool",
|
"actix-threadpool",
|
||||||
|
"actix-tower",
|
||||||
"actix-utils",
|
"actix-utils",
|
||||||
"router",
|
"router",
|
||||||
]
|
]
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
//! * `ssl` - enables ssl support via `openssl` crate
|
//! * `ssl` - enables ssl support via `openssl` crate
|
||||||
//! * `rust-tls` - enables ssl support via `rustls` crate
|
//! * `rust-tls` - enables ssl support via `rustls` crate
|
||||||
|
|
||||||
|
#![recursion_limit = "128"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
@ -6,11 +6,12 @@
|
|||||||
|
|
||||||
* Add `Debug` impl for `SslError`
|
* Add `Debug` impl for `SslError`
|
||||||
|
|
||||||
|
* Derive debug for Server and ServerCommand
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
* Upgrade to actix-service 0.4
|
* Upgrade to actix-service 0.4
|
||||||
|
|
||||||
|
|
||||||
## [0.4.3] - 2019-04-16
|
## [0.4.3] - 2019-04-16
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -5,6 +5,7 @@ use futures::Future;
|
|||||||
use crate::builder::ServerBuilder;
|
use crate::builder::ServerBuilder;
|
||||||
use crate::signals::Signal;
|
use crate::signals::Signal;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub(crate) enum ServerCommand {
|
pub(crate) enum ServerCommand {
|
||||||
WorkerDied(usize),
|
WorkerDied(usize),
|
||||||
Pause(oneshot::Sender<()>),
|
Pause(oneshot::Sender<()>),
|
||||||
@ -17,7 +18,7 @@ pub(crate) enum ServerCommand {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Server(UnboundedSender<ServerCommand>);
|
pub struct Server(UnboundedSender<ServerCommand>);
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
|
2
actix-tower/CHANGES.md
Normal file
2
actix-tower/CHANGES.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Changes
|
||||||
|
|
29
actix-tower/Cargo.toml
Normal file
29
actix-tower/Cargo.toml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
[package]
|
||||||
|
name = "actix-tower"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>", "Marcus Griep <marcus@griep.us>"]
|
||||||
|
description = "Actix Tower"
|
||||||
|
keywords = ["network", "framework", "async", "futures"]
|
||||||
|
homepage = "https://actix.rs"
|
||||||
|
repository = "https://github.com/actix/actix-net.git"
|
||||||
|
documentation = "https://docs.rs/actix-tower/"
|
||||||
|
categories = ["network-programming", "asynchronous"]
|
||||||
|
license = "MIT/Apache-2.0"
|
||||||
|
exclude = [".gitignore", ".travis.yml", ".cargo/config", "appveyor.yml"]
|
||||||
|
edition = "2018"
|
||||||
|
workspace = ".."
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "actix/actix-tower", branch = "master" }
|
||||||
|
appveyor = { repository = "actix/actix-net" }
|
||||||
|
codecov = { repository = "actix/actix-tower", branch = "master", service = "github" }
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "actix_tower"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
actix-service = "0.3.6"
|
||||||
|
futures = "0.1.24"
|
||||||
|
tower-service = "0.2.0"
|
||||||
|
|
191
actix-tower/src/lib.rs
Normal file
191
actix-tower/src/lib.rs
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
//! Utilities to ease interoperability with services based on the `tower-service` crate.
|
||||||
|
|
||||||
|
use actix_service::Service as ActixService;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use tower_service::Service as TowerService;
|
||||||
|
|
||||||
|
/// Compatibility wrapper associating a `tower_service::Service` with a particular
|
||||||
|
/// `Request` type, so that it can be used as an `actix_service::Service`.
|
||||||
|
pub struct TowerCompat<S, R> {
|
||||||
|
inner: S,
|
||||||
|
_phantom: PhantomData<R>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, R> TowerCompat<S, R> {
|
||||||
|
/// Wraps a `tower_service::Service` in a compatibility wrapper.
|
||||||
|
pub fn new(inner: S) -> Self {
|
||||||
|
TowerCompat {
|
||||||
|
inner,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extension trait for wrapping `tower_service::Service` instances for use as
|
||||||
|
/// an `actix_service::Service`.
|
||||||
|
pub trait TowerServiceExt {
|
||||||
|
/// Wraps a `tower_service::Service` in a compatibility wrapper.
|
||||||
|
fn compat<R>(self) -> TowerCompat<Self, R>
|
||||||
|
where
|
||||||
|
Self: TowerService<R> + Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> TowerServiceExt for S {
|
||||||
|
fn compat<R>(self) -> TowerCompat<Self, R>
|
||||||
|
where
|
||||||
|
Self: TowerService<R> + Sized
|
||||||
|
{
|
||||||
|
TowerCompat::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, R> ActixService for TowerCompat<S, R>
|
||||||
|
where
|
||||||
|
S: TowerService<R>,
|
||||||
|
{
|
||||||
|
type Request = R;
|
||||||
|
type Response = S::Response;
|
||||||
|
type Error = S::Error;
|
||||||
|
type Future = S::Future;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> futures::Poll<(), Self::Error> {
|
||||||
|
TowerService::poll_ready(&mut self.inner)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||||
|
TowerService::call(&mut self.inner, req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::TowerServiceExt;
|
||||||
|
use actix_service::{Service as ActixService, ServiceExt, Transform};
|
||||||
|
use futures::{future::FutureResult, Async, Poll, Future};
|
||||||
|
use tower_service::Service as TowerService;
|
||||||
|
|
||||||
|
struct RandomService;
|
||||||
|
impl<R> TowerService<R> for RandomService {
|
||||||
|
type Response = u32;
|
||||||
|
type Error = ();
|
||||||
|
type Future = FutureResult<Self::Response, Self::Error>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
Ok(Async::Ready(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, _req: R) -> Self::Future {
|
||||||
|
futures::finished(4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tower_service_as_actix_service_returns_4() {
|
||||||
|
let mut s = RandomService.compat();
|
||||||
|
|
||||||
|
assert_eq!(Ok(Async::Ready(())), s.poll_ready());
|
||||||
|
|
||||||
|
assert_eq!(Ok(Async::Ready(4)), s.call(()).poll());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tower_service_as_actix_service_can_combine() {
|
||||||
|
let mut s = RandomService.compat().map(|x| x + 1);
|
||||||
|
|
||||||
|
assert_eq!(Ok(Async::Ready(())), s.poll_ready());
|
||||||
|
|
||||||
|
assert_eq!(Ok(Async::Ready(5)), s.call(()).poll());
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AddOneService;
|
||||||
|
impl TowerService<u32> for AddOneService {
|
||||||
|
type Response = u32;
|
||||||
|
type Error = ();
|
||||||
|
type Future = FutureResult<Self::Response, Self::Error>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
Ok(Async::Ready(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: u32) -> Self::Future {
|
||||||
|
futures::finished(req + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tower_services_as_actix_services_chained() {
|
||||||
|
let s1 = RandomService.compat();
|
||||||
|
let s2 = AddOneService.compat();
|
||||||
|
let s3 = AddOneService.compat();
|
||||||
|
|
||||||
|
let mut s = s1.and_then(s2).and_then(s3);
|
||||||
|
|
||||||
|
assert_eq!(Ok(Async::Ready(())), s.poll_ready());
|
||||||
|
|
||||||
|
assert_eq!(Ok(Async::Ready(6)), s.call(()).poll());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tower_services_as_actix_services_chained_2() {
|
||||||
|
let s1 = RandomService.compat();
|
||||||
|
let s2 = AddOneService.compat();
|
||||||
|
let s3 = AddOneService.compat();
|
||||||
|
let s4 = RandomService.compat();
|
||||||
|
|
||||||
|
let mut s = s1.and_then(s2).and_then(s3).and_then(s4);
|
||||||
|
|
||||||
|
assert_eq!(Ok(Async::Ready(())), s.poll_ready());
|
||||||
|
|
||||||
|
assert_eq!(Ok(Async::Ready(4)), s.call(()).poll());
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DoMathTransform<S>(S);
|
||||||
|
impl<S> ActixService for DoMathTransform<S>
|
||||||
|
where
|
||||||
|
S: ActixService<Response = u32>,
|
||||||
|
S::Future: 'static,
|
||||||
|
{
|
||||||
|
type Request = S::Request;
|
||||||
|
type Response = u32;
|
||||||
|
type Error = S::Error;
|
||||||
|
type Future = Box<dyn Future<Item = Self::Response, Error = Self::Error>>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
self.0.poll_ready()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||||
|
let fut = self.0.call(req).map(|x| x * 17);
|
||||||
|
Box::new(fut)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DoMath;
|
||||||
|
impl<S> Transform<S> for DoMath
|
||||||
|
where
|
||||||
|
S: ActixService<Response = u32>,
|
||||||
|
S::Future: 'static,
|
||||||
|
{
|
||||||
|
type Request = S::Request;
|
||||||
|
type Response = u32;
|
||||||
|
type Error = S::Error;
|
||||||
|
type Transform = DoMathTransform<S>;
|
||||||
|
type InitError = ();
|
||||||
|
type Future = FutureResult<Self::Transform, Self::InitError>;
|
||||||
|
|
||||||
|
fn new_transform(&self, service: S) -> Self::Future {
|
||||||
|
futures::finished(DoMathTransform(service))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tower_service_as_actix_service_can_be_transformed() {
|
||||||
|
let transform = DoMath;
|
||||||
|
|
||||||
|
let mut s = transform.new_transform(RandomService.compat()).wait().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(Ok(Async::Ready(())), s.poll_ready());
|
||||||
|
|
||||||
|
assert_eq!(Ok(Async::Ready(68)), s.call(()).poll());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user