mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-24 03:42:59 +01:00
migrate to tokio 0.2.2
This commit is contained in:
parent
d49aca9595
commit
3a858feaec
@ -1,5 +1,11 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
## [1.0.0-alpha.3] - 2019-12-xx
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Migrate to `tokio=0.2.2`
|
||||||
|
|
||||||
## [1.0.0-alpha.2] - 2019-12-02
|
## [1.0.0-alpha.2] - 2019-12-02
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-connect"
|
name = "actix-connect"
|
||||||
version = "1.0.0-alpha.2"
|
version = "1.0.0-alpha.3"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix connect - tcp connector service"
|
description = "Actix connect - tcp connector service"
|
||||||
keywords = ["network", "framework", "async", "futures"]
|
keywords = ["network", "framework", "async", "futures"]
|
||||||
@ -27,33 +27,33 @@ default = ["uri"]
|
|||||||
openssl = ["open-ssl", "tokio-openssl"]
|
openssl = ["open-ssl", "tokio-openssl"]
|
||||||
|
|
||||||
# rustls
|
# rustls
|
||||||
# rustls = ["rust-tls", "tokio-rustls", "webpki"]
|
rustls = ["rust-tls", "tokio-rustls", "webpki"]
|
||||||
|
|
||||||
# support http::Uri as connect address
|
# support http::Uri as connect address
|
||||||
uri = ["http"]
|
uri = ["http"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-service = "1.0.0-alpha.3"
|
actix-service = "1.0.0-alpha.3"
|
||||||
actix-codec = "0.2.0-alpha.2"
|
actix-codec = "0.2.0-alpha.3"
|
||||||
actix-utils = "1.0.0-alpha.2"
|
actix-utils = "1.0.0-alpha.3"
|
||||||
actix-rt = "1.0.0-alpha.2"
|
actix-rt = "1.0.0-alpha.3"
|
||||||
derive_more = "0.99.2"
|
derive_more = "0.99.2"
|
||||||
either = "1.5.2"
|
either = "1.5.2"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
http = { version = "0.1.17", optional = true }
|
http = { version = "0.2.0", optional = true }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
trust-dns-resolver = { version="0.18.0-alpha.1", default-features = false }
|
# trust-dns-resolver = { version="0.18.0", default-features = false }
|
||||||
|
trust-dns-resolver = { git = "https://github.com/bluejekyll/trust-dns.git", branch = "update-tokio-0.2-alpha.2" }
|
||||||
|
|
||||||
# openssl
|
# openssl
|
||||||
open-ssl = { version="0.10", package = "openssl", optional = true }
|
open-ssl = { version="0.10", package = "openssl", optional = true }
|
||||||
tokio-openssl = { version = "0.4.0-alpha.6", optional = true }
|
tokio-openssl = { version = "0.4.0", optional = true }
|
||||||
|
|
||||||
# rustls
|
# rustls
|
||||||
rust-tls = { version = "0.16.0", package = "rustls", optional = true }
|
rust-tls = { version = "0.16.0", package = "rustls", optional = true }
|
||||||
# tokio-rustls = { version = "0.10.0", optional = true }
|
tokio-rustls = { version = "0.12.0", optional = true }
|
||||||
# tokio-rustls = { git = "https://github.com/quininer/tokio-rustls.git", branch = "tokio-0.2", optional = true }
|
|
||||||
webpki = { version = "0.21", optional = true }
|
webpki = { version = "0.21", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
bytes = "0.4"
|
bytes = "0.5.2"
|
||||||
actix-testing = { version="1.0.0-alpha.2" }
|
actix-testing = { version="1.0.0-alpha.2" }
|
||||||
|
@ -14,7 +14,7 @@ extern crate log;
|
|||||||
mod connect;
|
mod connect;
|
||||||
mod connector;
|
mod connector;
|
||||||
mod error;
|
mod error;
|
||||||
mod resolver;
|
mod resolve;
|
||||||
mod service;
|
mod service;
|
||||||
pub mod ssl;
|
pub mod ssl;
|
||||||
|
|
||||||
@ -23,15 +23,20 @@ mod uri;
|
|||||||
|
|
||||||
use actix_rt::{net::TcpStream, Arbiter};
|
use actix_rt::{net::TcpStream, Arbiter};
|
||||||
use actix_service::{pipeline, pipeline_factory, Service, ServiceFactory};
|
use actix_service::{pipeline, pipeline_factory, Service, ServiceFactory};
|
||||||
|
use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
|
||||||
|
use trust_dns_resolver::system_conf::read_system_conf;
|
||||||
|
use trust_dns_resolver::AsyncResolver;
|
||||||
|
|
||||||
pub use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
|
pub mod resolver {
|
||||||
pub use trust_dns_resolver::system_conf::read_system_conf;
|
pub use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
|
||||||
pub use trust_dns_resolver::{error::ResolveError, AsyncResolver};
|
pub use trust_dns_resolver::system_conf::read_system_conf;
|
||||||
|
pub use trust_dns_resolver::{error::ResolveError, AsyncResolver};
|
||||||
|
}
|
||||||
|
|
||||||
pub use self::connect::{Address, Connect, Connection};
|
pub use self::connect::{Address, Connect, Connection};
|
||||||
pub use self::connector::{TcpConnector, TcpConnectorFactory};
|
pub use self::connector::{TcpConnector, TcpConnectorFactory};
|
||||||
pub use self::error::ConnectError;
|
pub use self::error::ConnectError;
|
||||||
pub use self::resolver::{Resolver, ResolverFactory};
|
pub use self::resolve::{Resolver, ResolverFactory};
|
||||||
pub use self::service::{ConnectService, ConnectServiceFactory, TcpConnectService};
|
pub use self::service::{ConnectService, ConnectServiceFactory, TcpConnectService};
|
||||||
|
|
||||||
pub fn start_resolver(cfg: ResolverConfig, opts: ResolverOpts) -> AsyncResolver {
|
pub fn start_resolver(cfg: ResolverConfig, opts: ResolverOpts) -> AsyncResolver {
|
||||||
|
@ -11,7 +11,7 @@ use trust_dns_resolver::AsyncResolver;
|
|||||||
use crate::connect::{Address, Connect, Connection};
|
use crate::connect::{Address, Connect, Connection};
|
||||||
use crate::connector::{TcpConnector, TcpConnectorFactory};
|
use crate::connector::{TcpConnector, TcpConnectorFactory};
|
||||||
use crate::error::ConnectError;
|
use crate::error::ConnectError;
|
||||||
use crate::resolver::{Resolver, ResolverFactory};
|
use crate::resolve::{Resolver, ResolverFactory};
|
||||||
|
|
||||||
pub struct ConnectServiceFactory<T> {
|
pub struct ConnectServiceFactory<T> {
|
||||||
tcp: TcpConnectorFactory<T>,
|
tcp: TcpConnectorFactory<T>,
|
||||||
|
@ -62,7 +62,7 @@ where
|
|||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Future = Ready<Result<Self::Service, Self::InitError>>;
|
type Future = Ready<Result<Self::Service, Self::InitError>>;
|
||||||
|
|
||||||
fn new_service(&self, _: &()) -> Self::Future {
|
fn new_service(&self, _: ()) -> Self::Future {
|
||||||
ok(RustlsConnectorService {
|
ok(RustlsConnectorService {
|
||||||
connector: self.connector.clone(),
|
connector: self.connector.clone(),
|
||||||
_t: PhantomData,
|
_t: PhantomData,
|
||||||
@ -93,7 +93,7 @@ where
|
|||||||
type Error = std::io::Error;
|
type Error = std::io::Error;
|
||||||
type Future = ConnectAsyncExt<T, U>;
|
type Future = ConnectAsyncExt<T, U>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ where
|
|||||||
{
|
{
|
||||||
type Output = Result<Connection<T, TlsStream<U>>, std::io::Error>;
|
type Output = Result<Connection<T, TlsStream<U>>, std::io::Error>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.get_mut();
|
let this = self.get_mut();
|
||||||
Poll::Ready(
|
Poll::Ready(
|
||||||
futures::ready!(Pin::new(&mut this.fut).poll(cx)).map(|stream| {
|
futures::ready!(Pin::new(&mut this.fut).poll(cx)).map(|stream| {
|
||||||
|
@ -6,8 +6,8 @@ use actix_service::{service_fn, Service, ServiceFactory};
|
|||||||
use actix_testing::TestServer;
|
use actix_testing::TestServer;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::SinkExt;
|
use futures::SinkExt;
|
||||||
use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
|
|
||||||
|
|
||||||
|
use actix_connect::resolver::{ResolverConfig, ResolverOpts};
|
||||||
use actix_connect::Connect;
|
use actix_connect::Connect;
|
||||||
|
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "openssl")]
|
||||||
@ -97,7 +97,7 @@ async fn test_new_service() {
|
|||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "openssl")]
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_uri() {
|
async fn test_uri() {
|
||||||
use http::HttpTryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
let srv = TestServer::with(|| {
|
let srv = TestServer::with(|| {
|
||||||
service_fn(|io: TcpStream| {
|
service_fn(|io: TcpStream| {
|
||||||
@ -118,7 +118,7 @@ async fn test_uri() {
|
|||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "rustls")]
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_rustls_uri() {
|
async fn test_rustls_uri() {
|
||||||
use http::HttpTryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
let srv = TestServer::with(|| {
|
let srv = TestServer::with(|| {
|
||||||
service_fn(|io: TcpStream| {
|
service_fn(|io: TcpStream| {
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
## [0.3.0-alpha.3] - 2019-12-xx
|
||||||
|
|
||||||
|
* Migrate to `tokio=0.2.2`
|
||||||
|
|
||||||
## [0.3.0-alpha.2] - 2019-12-02
|
## [0.3.0-alpha.2] - 2019-12-02
|
||||||
|
|
||||||
* Migrate to `std::future`
|
* Migrate to `std::future`
|
||||||
|
|
||||||
|
|
||||||
## [0.1.1] - 2019-10-14
|
## [0.1.1] - 2019-10-14
|
||||||
|
|
||||||
* Re-register task on every dispatcher poll.
|
* Re-register task on every dispatcher poll.
|
||||||
|
|
||||||
|
|
||||||
## [0.1.0] - 2019-09-25
|
## [0.1.0] - 2019-09-25
|
||||||
|
|
||||||
* Initial release
|
* Initial release
|
||||||
|
@ -22,7 +22,7 @@ actix-service = "1.0.0-alpha.3"
|
|||||||
actix-codec = "0.2.0-alpha.2"
|
actix-codec = "0.2.0-alpha.2"
|
||||||
actix-utils = "1.0.0-alpha.2"
|
actix-utils = "1.0.0-alpha.2"
|
||||||
actix-rt = "1.0.0-alpha.2"
|
actix-rt = "1.0.0-alpha.2"
|
||||||
bytes = "0.4"
|
bytes = "0.5"
|
||||||
either = "1.5.2"
|
either = "1.5.2"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
pin-project = "0.4.6"
|
pin-project = "0.4.6"
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
* Fix compilation on non-unix platforms
|
* Fix compilation on non-unix platforms
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Migrate to `tokio=0.2.2`
|
||||||
|
|
||||||
|
|
||||||
## [1.0.0-alpha.2] - 2019-12-02
|
## [1.0.0-alpha.2] - 2019-12-02
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-rt"
|
name = "actix-rt"
|
||||||
version = "1.0.0-alpha.2"
|
version = "1.0.0-alpha.3"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix runtime"
|
description = "Actix runtime"
|
||||||
keywords = ["network", "framework", "async", "futures"]
|
keywords = ["network", "framework", "async", "futures"]
|
||||||
@ -22,8 +22,4 @@ actix-macros = "0.1.0-alpha.1"
|
|||||||
actix-threadpool = "0.3"
|
actix-threadpool = "0.3"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
copyless = "0.1.4"
|
copyless = "0.1.4"
|
||||||
|
tokio = { version = "0.2.2", default-features=false, features=["rt-core", "rt-util", "io-driver", "tcp", "uds", "udp", "time", "signal"] }
|
||||||
tokio = { version = "=0.2.0-alpha.6", features=["rt-current-thread","tcp","uds","udp","timer","signal"] }
|
|
||||||
tokio-executor = "=0.2.0-alpha.6"
|
|
||||||
tokio-net = "=0.2.0-alpha.6"
|
|
||||||
tokio-timer = "=0.3.0-alpha.6"
|
|
||||||
|
@ -9,9 +9,8 @@ use std::{fmt, thread};
|
|||||||
use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
|
use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
|
||||||
use futures::channel::oneshot::{channel, Canceled, Sender};
|
use futures::channel::oneshot::{channel, Canceled, Sender};
|
||||||
use futures::{future, Future, FutureExt, Stream};
|
use futures::{future, Future, FutureExt, Stream};
|
||||||
use tokio_executor::current_thread::spawn;
|
|
||||||
|
|
||||||
use crate::builder::Builder;
|
use crate::runtime::Runtime;
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
|
|
||||||
use copyless::BoxHelper;
|
use copyless::BoxHelper;
|
||||||
@ -19,7 +18,7 @@ use copyless::BoxHelper;
|
|||||||
thread_local!(
|
thread_local!(
|
||||||
static ADDR: RefCell<Option<Arbiter>> = RefCell::new(None);
|
static ADDR: RefCell<Option<Arbiter>> = RefCell::new(None);
|
||||||
static RUNNING: Cell<bool> = Cell::new(false);
|
static RUNNING: Cell<bool> = Cell::new(false);
|
||||||
static Q: RefCell<Vec<Box<dyn Future<Output = ()>>>> = RefCell::new(Vec::new());
|
static Q: RefCell<Vec<Pin<Box<dyn Future<Output = ()>>>>> = RefCell::new(Vec::new());
|
||||||
static STORAGE: RefCell<HashMap<TypeId, Box<dyn Any>>> = RefCell::new(HashMap::new());
|
static STORAGE: RefCell<HashMap<TypeId, Box<dyn Any>>> = RefCell::new(HashMap::new());
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -101,7 +100,7 @@ impl Arbiter {
|
|||||||
let handle = thread::Builder::new()
|
let handle = thread::Builder::new()
|
||||||
.name(name.clone())
|
.name(name.clone())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
let mut rt = Builder::new().build_rt().expect("Can not create Runtime");
|
let mut rt = Runtime::new().expect("Can not create Runtime");
|
||||||
let arb = Arbiter::with_sender(arb_tx);
|
let arb = Arbiter::with_sender(arb_tx);
|
||||||
|
|
||||||
let (stop, stop_rx) = channel();
|
let (stop, stop_rx) = channel();
|
||||||
@ -143,14 +142,16 @@ impl Arbiter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn run_system() {
|
pub(crate) fn run_system(rt: Option<&Runtime>) {
|
||||||
RUNNING.with(|cell| cell.set(true));
|
RUNNING.with(|cell| cell.set(true));
|
||||||
Q.with(|cell| {
|
Q.with(|cell| {
|
||||||
let mut v = cell.borrow_mut();
|
let mut v = cell.borrow_mut();
|
||||||
for fut in v.drain(..) {
|
for fut in v.drain(..) {
|
||||||
// We pin the boxed future, so it can never again be moved.
|
if let Some(rt) = rt {
|
||||||
let fut = unsafe { Pin::new_unchecked(fut) };
|
rt.spawn(fut);
|
||||||
tokio_executor::current_thread::spawn(fut);
|
} else {
|
||||||
|
tokio::task::spawn_local(fut);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -169,11 +170,14 @@ impl Arbiter {
|
|||||||
RUNNING.with(move |cell| {
|
RUNNING.with(move |cell| {
|
||||||
if cell.get() {
|
if cell.get() {
|
||||||
// Spawn the future on running executor
|
// Spawn the future on running executor
|
||||||
spawn(future);
|
tokio::task::spawn_local(future);
|
||||||
} else {
|
} else {
|
||||||
// Box the future and push it to the queue, this results in double boxing
|
// Box the future and push it to the queue, this results in double boxing
|
||||||
// because the executor boxes the future again, but works for now
|
// because the executor boxes the future again, but works for now
|
||||||
Q.with(move |cell| cell.borrow_mut().push(Box::alloc().init(future)));
|
Q.with(move |cell| {
|
||||||
|
cell.borrow_mut()
|
||||||
|
.push(unsafe { Pin::new_unchecked(Box::alloc().init(future)) })
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -325,7 +329,7 @@ impl Future for ArbiterController {
|
|||||||
return Poll::Ready(());
|
return Poll::Ready(());
|
||||||
}
|
}
|
||||||
ArbiterCommand::Execute(fut) => {
|
ArbiterCommand::Execute(fut) => {
|
||||||
spawn(fut);
|
tokio::task::spawn_local(fut);
|
||||||
}
|
}
|
||||||
ArbiterCommand::ExecuteFn(f) => {
|
ArbiterCommand::ExecuteFn(f) => {
|
||||||
f.call_box();
|
f.call_box();
|
||||||
|
@ -4,11 +4,7 @@ use std::io;
|
|||||||
use futures::channel::mpsc::unbounded;
|
use futures::channel::mpsc::unbounded;
|
||||||
use futures::channel::oneshot::{channel, Receiver};
|
use futures::channel::oneshot::{channel, Receiver};
|
||||||
use futures::future::{lazy, Future, FutureExt};
|
use futures::future::{lazy, Future, FutureExt};
|
||||||
|
use tokio::task::LocalSet;
|
||||||
use tokio::runtime::current_thread::Handle;
|
|
||||||
use tokio_executor::current_thread::CurrentThread;
|
|
||||||
use tokio_net::driver::Reactor;
|
|
||||||
use tokio_timer::{clock::Clock, timer::Timer};
|
|
||||||
|
|
||||||
use crate::arbiter::{Arbiter, SystemArbiter};
|
use crate::arbiter::{Arbiter, SystemArbiter};
|
||||||
use crate::runtime::Runtime;
|
use crate::runtime::Runtime;
|
||||||
@ -23,9 +19,6 @@ pub struct Builder {
|
|||||||
/// Name of the System. Defaults to "actix" if unset.
|
/// Name of the System. Defaults to "actix" if unset.
|
||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
|
|
||||||
/// The clock to use
|
|
||||||
clock: Clock,
|
|
||||||
|
|
||||||
/// Whether the Arbiter will stop the whole System on uncaught panic. Defaults to false.
|
/// Whether the Arbiter will stop the whole System on uncaught panic. Defaults to false.
|
||||||
stop_on_panic: bool,
|
stop_on_panic: bool,
|
||||||
}
|
}
|
||||||
@ -34,7 +27,6 @@ impl Builder {
|
|||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
Builder {
|
Builder {
|
||||||
name: Cow::Borrowed("actix"),
|
name: Cow::Borrowed("actix"),
|
||||||
clock: Clock::new(),
|
|
||||||
stop_on_panic: false,
|
stop_on_panic: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,14 +37,6 @@ impl Builder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the Clock instance that will be used by this System.
|
|
||||||
///
|
|
||||||
/// Defaults to the system clock.
|
|
||||||
pub fn clock(mut self, clock: Clock) -> Self {
|
|
||||||
self.clock = clock;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the option 'stop_on_panic' which controls whether the System is stopped when an
|
/// Sets the option 'stop_on_panic' which controls whether the System is stopped when an
|
||||||
/// uncaught panic is thrown from a worker thread.
|
/// uncaught panic is thrown from a worker thread.
|
||||||
///
|
///
|
||||||
@ -72,8 +56,8 @@ impl Builder {
|
|||||||
/// Create new System that can run asynchronously.
|
/// Create new System that can run asynchronously.
|
||||||
///
|
///
|
||||||
/// This method panics if it cannot start the system arbiter
|
/// This method panics if it cannot start the system arbiter
|
||||||
pub(crate) fn build_async(self, executor: Handle) -> AsyncSystemRunner {
|
pub(crate) fn build_async(self, local: &LocalSet) -> AsyncSystemRunner {
|
||||||
self.create_async_runtime(executor)
|
self.create_async_runtime(local)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function will start tokio runtime and will finish once the
|
/// This function will start tokio runtime and will finish once the
|
||||||
@ -86,7 +70,7 @@ impl Builder {
|
|||||||
self.create_runtime(f).run()
|
self.create_runtime(f).run()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_async_runtime(self, executor: Handle) -> AsyncSystemRunner {
|
fn create_async_runtime(self, local: &LocalSet) -> AsyncSystemRunner {
|
||||||
let (stop_tx, stop) = channel();
|
let (stop_tx, stop) = channel();
|
||||||
let (sys_sender, sys_receiver) = unbounded();
|
let (sys_sender, sys_receiver) = unbounded();
|
||||||
|
|
||||||
@ -96,7 +80,7 @@ impl Builder {
|
|||||||
let arb = SystemArbiter::new(stop_tx, sys_receiver);
|
let arb = SystemArbiter::new(stop_tx, sys_receiver);
|
||||||
|
|
||||||
// start the system arbiter
|
// start the system arbiter
|
||||||
executor.spawn(arb).expect("could not start system arbiter");
|
let _ = local.spawn_local(arb);
|
||||||
|
|
||||||
AsyncSystemRunner { stop, system }
|
AsyncSystemRunner { stop, system }
|
||||||
}
|
}
|
||||||
@ -113,40 +97,14 @@ impl Builder {
|
|||||||
// system arbiter
|
// system arbiter
|
||||||
let arb = SystemArbiter::new(stop_tx, sys_receiver);
|
let arb = SystemArbiter::new(stop_tx, sys_receiver);
|
||||||
|
|
||||||
let mut rt = self.build_rt().unwrap();
|
let mut rt = Runtime::new().unwrap();
|
||||||
rt.spawn(arb);
|
rt.spawn(arb);
|
||||||
|
|
||||||
// init system arbiter and run configuration method
|
// init system arbiter and run configuration method
|
||||||
let _ = rt.block_on(lazy(move |_| {
|
rt.block_on(lazy(move |_| f()));
|
||||||
f();
|
|
||||||
Ok::<_, ()>(())
|
|
||||||
}));
|
|
||||||
|
|
||||||
SystemRunner { rt, stop, system }
|
SystemRunner { rt, stop, system }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn build_rt(&self) -> io::Result<Runtime> {
|
|
||||||
// We need a reactor to receive events about IO objects from kernel
|
|
||||||
let reactor = Reactor::new()?;
|
|
||||||
let reactor_handle = reactor.handle();
|
|
||||||
|
|
||||||
// Place a timer wheel on top of the reactor. If there are no timeouts to fire, it'll let the
|
|
||||||
// reactor pick up some new external events.
|
|
||||||
let timer = Timer::new_with_now(reactor, self.clock.clone());
|
|
||||||
let timer_handle = timer.handle();
|
|
||||||
|
|
||||||
// And now put a single-threaded executor on top of the timer. When there are no futures ready
|
|
||||||
// to do something, it'll let the timer or the reactor to generate some new stimuli for the
|
|
||||||
// futures to continue in their life.
|
|
||||||
let executor = CurrentThread::new_with_park(timer);
|
|
||||||
|
|
||||||
Ok(Runtime::new2(
|
|
||||||
reactor_handle,
|
|
||||||
timer_handle,
|
|
||||||
self.clock.clone(),
|
|
||||||
executor,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -163,7 +121,7 @@ impl AsyncSystemRunner {
|
|||||||
|
|
||||||
// run loop
|
// run loop
|
||||||
lazy(|_| {
|
lazy(|_| {
|
||||||
Arbiter::run_system();
|
Arbiter::run_system(None);
|
||||||
async {
|
async {
|
||||||
let res = match stop.await {
|
let res = match stop.await {
|
||||||
Ok(code) => {
|
Ok(code) => {
|
||||||
@ -202,10 +160,7 @@ impl SystemRunner {
|
|||||||
let SystemRunner { mut rt, stop, .. } = self;
|
let SystemRunner { mut rt, stop, .. } = self;
|
||||||
|
|
||||||
// run loop
|
// run loop
|
||||||
let _ = rt.block_on(async {
|
Arbiter::run_system(Some(&rt));
|
||||||
Arbiter::run_system();
|
|
||||||
Ok::<_, ()>(())
|
|
||||||
});
|
|
||||||
let result = match rt.block_on(stop) {
|
let result = match rt.block_on(stop) {
|
||||||
Ok(code) => {
|
Ok(code) => {
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
@ -226,17 +181,11 @@ impl SystemRunner {
|
|||||||
/// Execute a future and wait for result.
|
/// Execute a future and wait for result.
|
||||||
pub fn block_on<F, O>(&mut self, fut: F) -> O
|
pub fn block_on<F, O>(&mut self, fut: F) -> O
|
||||||
where
|
where
|
||||||
F: Future<Output = O>,
|
F: Future<Output = O> + 'static,
|
||||||
{
|
{
|
||||||
self.rt.block_on(async {
|
Arbiter::run_system(Some(&self.rt));
|
||||||
Arbiter::run_system();
|
|
||||||
});
|
|
||||||
|
|
||||||
let res = self.rt.block_on(fut);
|
let res = self.rt.block_on(fut);
|
||||||
self.rt.block_on(async {
|
Arbiter::stop_system();
|
||||||
Arbiter::stop_system();
|
|
||||||
});
|
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,9 +38,9 @@ where
|
|||||||
pub mod signal {
|
pub mod signal {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub mod unix {
|
pub mod unix {
|
||||||
pub use tokio_net::signal::unix::*;
|
pub use tokio::signal::unix::*;
|
||||||
}
|
}
|
||||||
pub use tokio_net::signal::{ctrl_c, CtrlC};
|
pub use tokio::signal::ctrl_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TCP/UDP/Unix bindings
|
/// TCP/UDP/Unix bindings
|
||||||
@ -59,21 +59,8 @@ pub mod net {
|
|||||||
|
|
||||||
/// Utilities for tracking time.
|
/// Utilities for tracking time.
|
||||||
pub mod time {
|
pub mod time {
|
||||||
use std::time::{Duration, Instant};
|
pub use tokio::time::Instant;
|
||||||
|
pub use tokio::time::{delay_for, delay_until, Delay};
|
||||||
pub use tokio_timer::Interval;
|
pub use tokio::time::{interval, interval_at, Interval};
|
||||||
pub use tokio_timer::{delay, delay_for, Delay};
|
pub use tokio::time::{timeout, Timeout};
|
||||||
pub use tokio_timer::{timeout, Timeout};
|
|
||||||
|
|
||||||
/// Creates new `Interval` that yields with interval of `duration`. The first
|
|
||||||
/// tick completes immediately.
|
|
||||||
pub fn interval(duration: Duration) -> Interval {
|
|
||||||
Interval::new(Instant::now(), duration)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates new `Interval` that yields with interval of `period` with the
|
|
||||||
/// first tick completing at `at`.
|
|
||||||
pub fn interval_at(start: Instant, duration: Duration) -> Interval {
|
|
||||||
Interval::new(start, duration)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
//! A runtime implementation that runs everything on the current thread.
|
|
||||||
//!
|
|
||||||
//! [`current_thread::Runtime`][rt] is similar to the primary
|
|
||||||
//! [`Runtime`][concurrent-rt] except that it runs all components on the current
|
|
||||||
//! thread instead of using a thread pool. This means that it is able to spawn
|
|
||||||
//! futures that do not implement `Send`.
|
|
||||||
//!
|
|
||||||
//! Same as the default [`Runtime`][concurrent-rt], the
|
|
||||||
//! [`current_thread::Runtime`][rt] includes:
|
|
||||||
//!
|
|
||||||
//! * A [reactor] to drive I/O resources.
|
|
||||||
//! * An [executor] to execute tasks that use these I/O resources.
|
|
||||||
//! * A [timer] for scheduling work to run after a set period of time.
|
|
||||||
//!
|
|
||||||
//! Note that [`current_thread::Runtime`][rt] does not implement `Send` itself
|
|
||||||
//! and cannot be safely moved to other threads.
|
|
||||||
//!
|
|
||||||
//! # Spawning from other threads
|
|
||||||
//!
|
|
||||||
//! While [`current_thread::Runtime`][rt] does not implement `Send` and cannot
|
|
||||||
//! safely be moved to other threads, it provides a `Handle` that can be sent
|
|
||||||
//! to other threads and allows to spawn new tasks from there.
|
|
||||||
//!
|
|
||||||
//! For example:
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! # extern crate tokio;
|
|
||||||
//! # extern crate futures;
|
|
||||||
//! use tokio::runtime::current_thread::Runtime;
|
|
||||||
//! use tokio::prelude::*;
|
|
||||||
//! use std::thread;
|
|
||||||
//!
|
|
||||||
//! # fn main() {
|
|
||||||
//! let mut runtime = Runtime::new().unwrap();
|
|
||||||
//! let handle = runtime.handle();
|
|
||||||
//!
|
|
||||||
//! thread::spawn(move || {
|
|
||||||
//! handle.spawn(future::ok(()));
|
|
||||||
//! }).join().unwrap();
|
|
||||||
//!
|
|
||||||
//! # /*
|
|
||||||
//! runtime.run().unwrap();
|
|
||||||
//! # */
|
|
||||||
//! # }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! # Examples
|
|
||||||
//!
|
|
||||||
//! Creating a new `Runtime` and running a future `f` until its completion and
|
|
||||||
//! returning its result.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! use tokio::runtime::current_thread::Runtime;
|
|
||||||
//! use tokio::prelude::*;
|
|
||||||
//!
|
|
||||||
//! let mut runtime = Runtime::new().unwrap();
|
|
||||||
//!
|
|
||||||
//! // Use the runtime...
|
|
||||||
//! // runtime.block_on(f); // where f is a future
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! [rt]: struct.Runtime.html
|
|
||||||
//! [concurrent-rt]: ../struct.Runtime.html
|
|
||||||
//! [chan]: https://docs.rs/futures/0.1/futures/sync/mpsc/fn.channel.html
|
|
||||||
//! [reactor]: ../../reactor/struct.Reactor.html
|
|
||||||
//! [executor]: https://tokio.rs/docs/getting-started/runtime-model/#executors
|
|
||||||
//! [timer]: ../../timer/index.html
|
|
||||||
|
|
||||||
mod builder;
|
|
||||||
mod runtime;
|
|
||||||
|
|
||||||
pub use self::builder::Builder;
|
|
||||||
pub use self::runtime::{Runtime, Handle};
|
|
||||||
pub use tokio_current_thread::spawn;
|
|
||||||
pub use tokio_current_thread::TaskExecutor;
|
|
||||||
|
|
||||||
use futures::Future;
|
|
||||||
|
|
||||||
/// Run the provided future to completion using a runtime running on the current thread.
|
|
||||||
///
|
|
||||||
/// This first creates a new [`Runtime`], and calls [`Runtime::block_on`] with the provided future,
|
|
||||||
/// which blocks the current thread until the provided future completes. It then calls
|
|
||||||
/// [`Runtime::run`] to wait for any other spawned futures to resolve.
|
|
||||||
pub fn block_on_all<F>(future: F) -> Result<F::Item, F::Error>
|
|
||||||
where
|
|
||||||
F: Future,
|
|
||||||
{
|
|
||||||
let mut r = Runtime::new().expect("failed to start runtime on current thread");
|
|
||||||
let v = r.block_on(future)?;
|
|
||||||
r.run().expect("failed to resolve remaining futures");
|
|
||||||
Ok(v)
|
|
||||||
}
|
|
@ -1,73 +1,36 @@
|
|||||||
use std::error::Error;
|
use std::future::Future;
|
||||||
use std::{fmt, io};
|
use std::io;
|
||||||
|
use tokio::{runtime, task::LocalSet};
|
||||||
use futures::Future;
|
|
||||||
use tokio_executor::current_thread::{self, CurrentThread};
|
|
||||||
use tokio_net::driver::{Handle as ReactorHandle, Reactor};
|
|
||||||
use tokio_timer::{
|
|
||||||
clock::Clock,
|
|
||||||
timer::{self, Timer},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::builder::Builder;
|
|
||||||
|
|
||||||
/// Single-threaded runtime provides a way to start reactor
|
/// Single-threaded runtime provides a way to start reactor
|
||||||
/// and executor on the current thread.
|
/// and runtime on the current thread.
|
||||||
///
|
///
|
||||||
/// See [module level][mod] documentation for more details.
|
/// See [module level][mod] documentation for more details.
|
||||||
///
|
///
|
||||||
/// [mod]: index.html
|
/// [mod]: index.html
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Runtime {
|
pub struct Runtime {
|
||||||
reactor_handle: ReactorHandle,
|
local: LocalSet,
|
||||||
timer_handle: timer::Handle,
|
rt: runtime::Runtime,
|
||||||
clock: Clock,
|
|
||||||
executor: CurrentThread<Timer<Reactor>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Error returned by the `run` function.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct RunError {
|
|
||||||
inner: current_thread::RunError,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for RunError {
|
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(fmt, "{}", self.inner)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for RunError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
self.inner.description()
|
|
||||||
}
|
|
||||||
fn cause(&self) -> Option<&dyn Error> {
|
|
||||||
self.inner.source()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Runtime {
|
impl Runtime {
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
/// Returns a new runtime initialized with default configuration values.
|
/// Returns a new runtime initialized with default configuration values.
|
||||||
pub fn new() -> io::Result<Runtime> {
|
pub fn new() -> io::Result<Runtime> {
|
||||||
Builder::new().build_rt()
|
let rt = runtime::Builder::new()
|
||||||
|
.enable_io()
|
||||||
|
.enable_time()
|
||||||
|
.basic_scheduler()
|
||||||
|
.build()?;
|
||||||
|
|
||||||
|
Ok(Runtime {
|
||||||
|
rt,
|
||||||
|
local: LocalSet::new(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn new2(
|
/// Spawn a future onto the single-threaded runtime.
|
||||||
reactor_handle: ReactorHandle,
|
|
||||||
timer_handle: timer::Handle,
|
|
||||||
clock: Clock,
|
|
||||||
executor: CurrentThread<Timer<Reactor>>,
|
|
||||||
) -> Runtime {
|
|
||||||
Runtime {
|
|
||||||
reactor_handle,
|
|
||||||
timer_handle,
|
|
||||||
clock,
|
|
||||||
executor,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Spawn a future onto the single-threaded Tokio runtime.
|
|
||||||
///
|
///
|
||||||
/// See [module level][mod] documentation for more details.
|
/// See [module level][mod] documentation for more details.
|
||||||
///
|
///
|
||||||
@ -75,7 +38,7 @@ impl Runtime {
|
|||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust,ignore
|
||||||
/// # use futures::{future, Future, Stream};
|
/// # use futures::{future, Future, Stream};
|
||||||
/// use actix_rt::Runtime;
|
/// use actix_rt::Runtime;
|
||||||
///
|
///
|
||||||
@ -95,11 +58,11 @@ impl Runtime {
|
|||||||
///
|
///
|
||||||
/// This function panics if the spawn fails. Failure occurs if the executor
|
/// This function panics if the spawn fails. Failure occurs if the executor
|
||||||
/// is currently at capacity and is unable to spawn a new future.
|
/// is currently at capacity and is unable to spawn a new future.
|
||||||
pub fn spawn<F>(&mut self, future: F) -> &mut Self
|
pub fn spawn<F>(&self, future: F) -> &Self
|
||||||
where
|
where
|
||||||
F: Future<Output = ()> + 'static,
|
F: Future<Output = ()> + 'static,
|
||||||
{
|
{
|
||||||
self.executor.spawn(future);
|
self.local.spawn_local(future);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,41 +84,9 @@ impl Runtime {
|
|||||||
/// complete execution by calling `block_on` or `run`.
|
/// complete execution by calling `block_on` or `run`.
|
||||||
pub fn block_on<F>(&mut self, f: F) -> F::Output
|
pub fn block_on<F>(&mut self, f: F) -> F::Output
|
||||||
where
|
where
|
||||||
F: Future,
|
F: Future + 'static,
|
||||||
{
|
{
|
||||||
self.enter(|executor| {
|
let res = self.local.block_on(&mut self.rt, f);
|
||||||
// Run the provided future
|
res
|
||||||
executor.block_on(f)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run the executor to completion, blocking the thread until **all**
|
|
||||||
/// spawned futures have completed.
|
|
||||||
pub fn run(&mut self) -> Result<(), RunError> {
|
|
||||||
self.enter(|executor| executor.run())
|
|
||||||
.map_err(|e| RunError { inner: e })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enter<F, R>(&mut self, f: F) -> R
|
|
||||||
where
|
|
||||||
F: FnOnce(&mut CurrentThread<Timer<Reactor>>) -> R,
|
|
||||||
{
|
|
||||||
let Runtime {
|
|
||||||
ref reactor_handle,
|
|
||||||
ref timer_handle,
|
|
||||||
ref clock,
|
|
||||||
ref mut executor,
|
|
||||||
..
|
|
||||||
} = *self;
|
|
||||||
|
|
||||||
// WARN: We do not enter the executor here, since in tokio 0.2 the executor is entered
|
|
||||||
// automatically inside its `block_on` and `run` methods
|
|
||||||
tokio_executor::with_default(&mut current_thread::TaskExecutor::current(), || {
|
|
||||||
tokio_timer::clock::with_default(clock, || {
|
|
||||||
let _reactor_guard = tokio_net::driver::set_default(reactor_handle);
|
|
||||||
let _timer_guard = tokio_timer::set_default(timer_handle);
|
|
||||||
f(executor)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use std::io;
|
|||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
use futures::channel::mpsc::UnboundedSender;
|
use futures::channel::mpsc::UnboundedSender;
|
||||||
use tokio::runtime::current_thread::Handle;
|
use tokio::task::LocalSet;
|
||||||
|
|
||||||
use crate::arbiter::{Arbiter, SystemCommand};
|
use crate::arbiter::{Arbiter, SystemCommand};
|
||||||
use crate::builder::{Builder, SystemRunner};
|
use crate::builder::{Builder, SystemRunner};
|
||||||
@ -58,16 +58,16 @@ impl System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
/// Create new system using provided CurrentThread Handle.
|
/// Create new system using provided tokio Handle.
|
||||||
///
|
///
|
||||||
/// This method panics if it can not spawn system arbiter
|
/// This method panics if it can not spawn system arbiter
|
||||||
pub fn run_in_executor<T: Into<String>>(
|
pub fn run_in_tokio<T: Into<String>>(
|
||||||
name: T,
|
name: T,
|
||||||
executor: Handle,
|
local: &LocalSet,
|
||||||
) -> impl Future<Output = Result<(), io::Error>> + Send {
|
) -> impl Future<Output = io::Result<()>> {
|
||||||
Self::builder()
|
Self::builder()
|
||||||
.name(name)
|
.name(name)
|
||||||
.build_async(executor)
|
.build_async(local)
|
||||||
.run_nonblocking()
|
.run_nonblocking()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
## [1.0.0-alpha.3] - 2019-12-xx
|
## [1.0.0-alpha.3] - 2019-12-xx
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Migrate to `tokio=0.2.2`
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
* Fix compilation on non-unix platforms
|
* Fix compilation on non-unix platforms
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-server"
|
name = "actix-server"
|
||||||
version = "1.0.0-alpha.2"
|
version = "1.0.0-alpha.3"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix server - General purpose tcp server"
|
description = "Actix server - General purpose tcp server"
|
||||||
keywords = ["network", "framework", "async", "futures"]
|
keywords = ["network", "framework", "async", "futures"]
|
||||||
@ -22,9 +22,9 @@ default = []
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-service = "1.0.0-alpha.3"
|
actix-service = "1.0.0-alpha.3"
|
||||||
actix-rt = "1.0.0-alpha.2"
|
actix-rt = "1.0.0-alpha.3"
|
||||||
actix-codec = "0.2.0-alpha.2"
|
actix-codec = "0.2.0-alpha.3"
|
||||||
actix-utils = "1.0.0-alpha.2"
|
actix-utils = "1.0.0-alpha.3"
|
||||||
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
num_cpus = "1.0"
|
num_cpus = "1.0"
|
||||||
@ -33,13 +33,10 @@ net2 = "0.2"
|
|||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
slab = "0.4"
|
slab = "0.4"
|
||||||
|
|
||||||
tokio-net = { version = "0.2.0-alpha.6", features = ["signal", "tcp", "uds"] }
|
|
||||||
futures-core-preview = "0.3.0-alpha.19"
|
|
||||||
|
|
||||||
# unix domain sockets
|
# unix domain sockets
|
||||||
mio-uds = { version = "0.6.7" }
|
mio-uds = { version = "0.6.7" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
bytes = "0.4"
|
bytes = "0.5"
|
||||||
env_logger = "0.6"
|
env_logger = "0.6"
|
||||||
actix-testing = "1.0.0-alpha.2"
|
actix-testing = "1.0.0-alpha.3"
|
@ -1,10 +1,9 @@
|
|||||||
use std::sync::mpsc as sync_mpsc;
|
use std::sync::mpsc as sync_mpsc;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::Duration;
|
||||||
use std::{io, thread};
|
use std::{io, thread};
|
||||||
|
|
||||||
use actix_rt::time::delay;
|
use actix_rt::time::{delay_until, Instant};
|
||||||
use actix_rt::System;
|
use actix_rt::System;
|
||||||
use futures::FutureExt;
|
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
|
|
||||||
@ -440,13 +439,10 @@ impl Accept {
|
|||||||
info.timeout = Some(Instant::now() + Duration::from_millis(500));
|
info.timeout = Some(Instant::now() + Duration::from_millis(500));
|
||||||
|
|
||||||
let r = self.timer.1.clone();
|
let r = self.timer.1.clone();
|
||||||
System::current().arbiter().send(
|
System::current().arbiter().send(Box::pin(async move {
|
||||||
async move {
|
delay_until(Instant::now() + Duration::from_millis(510)).await;
|
||||||
delay(Instant::now() + Duration::from_millis(510)).await;
|
let _ = r.set_readiness(mio::Ready::readable());
|
||||||
let _ = r.set_readiness(mio::Ready::readable());
|
}));
|
||||||
}
|
|
||||||
.boxed(),
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::Duration;
|
||||||
use std::{io, mem, net};
|
use std::{io, mem, net};
|
||||||
|
|
||||||
use actix_rt::net::TcpStream;
|
use actix_rt::net::TcpStream;
|
||||||
use actix_rt::{spawn, time::delay, Arbiter, System};
|
use actix_rt::time::{delay_until, Instant};
|
||||||
|
use actix_rt::{spawn, System};
|
||||||
use futures::channel::mpsc::{unbounded, UnboundedReceiver};
|
use futures::channel::mpsc::{unbounded, UnboundedReceiver};
|
||||||
use futures::channel::oneshot;
|
use futures::channel::oneshot;
|
||||||
use futures::future::ready;
|
use futures::future::ready;
|
||||||
@ -305,22 +306,11 @@ impl ServerBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn start_worker(&self, idx: usize, notify: AcceptNotify) -> WorkerClient {
|
fn start_worker(&self, idx: usize, notify: AcceptNotify) -> WorkerClient {
|
||||||
let (tx1, rx1) = unbounded();
|
|
||||||
let (tx2, rx2) = unbounded();
|
|
||||||
let timeout = self.shutdown_timeout;
|
|
||||||
let avail = WorkerAvailability::new(notify);
|
let avail = WorkerAvailability::new(notify);
|
||||||
let worker = WorkerClient::new(idx, tx1, tx2, avail.clone());
|
|
||||||
let services: Vec<Box<dyn InternalServiceFactory>> =
|
let services: Vec<Box<dyn InternalServiceFactory>> =
|
||||||
self.services.iter().map(|v| v.clone_factory()).collect();
|
self.services.iter().map(|v| v.clone_factory()).collect();
|
||||||
|
|
||||||
Arbiter::new().send(
|
Worker::start(idx, services, avail, self.shutdown_timeout)
|
||||||
async move {
|
|
||||||
Worker::start(rx1, rx2, services, avail, timeout);
|
|
||||||
}
|
|
||||||
.boxed(),
|
|
||||||
);
|
|
||||||
|
|
||||||
worker
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_cmd(&mut self, item: ServerCommand) {
|
fn handle_cmd(&mut self, item: ServerCommand) {
|
||||||
@ -395,8 +385,10 @@ impl ServerBuilder {
|
|||||||
if exit {
|
if exit {
|
||||||
spawn(
|
spawn(
|
||||||
async {
|
async {
|
||||||
delay(Instant::now() + Duration::from_millis(300))
|
delay_until(
|
||||||
.await;
|
Instant::now() + Duration::from_millis(300),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
System::current().stop();
|
System::current().stop();
|
||||||
}
|
}
|
||||||
.boxed(),
|
.boxed(),
|
||||||
@ -409,10 +401,12 @@ impl ServerBuilder {
|
|||||||
// we need to stop system if server was spawned
|
// we need to stop system if server was spawned
|
||||||
if self.exit {
|
if self.exit {
|
||||||
spawn(
|
spawn(
|
||||||
delay(Instant::now() + Duration::from_millis(300)).then(|_| {
|
delay_until(Instant::now() + Duration::from_millis(300)).then(
|
||||||
System::current().stop();
|
|_| {
|
||||||
ready(())
|
System::current().stop();
|
||||||
}),
|
ready(())
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if let Some(tx) = completion {
|
if let Some(tx) = completion {
|
||||||
|
@ -3,7 +3,7 @@ use std::io;
|
|||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use futures_core::stream::Stream;
|
use futures::future::lazy;
|
||||||
|
|
||||||
use crate::server::Server;
|
use crate::server::Server;
|
||||||
|
|
||||||
@ -33,11 +33,13 @@ pub(crate) struct Signals {
|
|||||||
|
|
||||||
impl Signals {
|
impl Signals {
|
||||||
pub(crate) fn start(srv: Server) -> io::Result<()> {
|
pub(crate) fn start(srv: Server) -> io::Result<()> {
|
||||||
actix_rt::spawn({
|
actix_rt::spawn(lazy(|_| {
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
{
|
{
|
||||||
let stream = actix_rt::signal::ctrl_c()?;
|
match actix_rt::signal::ctrl_c() {
|
||||||
Signals { srv, stream }
|
Ok(stream) => actix_rt::spawn(Signals { srv, stream }),
|
||||||
|
Err(e) => log::error!("Can not initialize ctrl-c handler err: {}", e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -54,12 +56,19 @@ impl Signals {
|
|||||||
];
|
];
|
||||||
|
|
||||||
for (kind, sig) in sig_map.iter() {
|
for (kind, sig) in sig_map.iter() {
|
||||||
streams.push((*sig, unix::signal(*kind)?));
|
match unix::signal(*kind) {
|
||||||
|
Ok(stream) => streams.push((*sig, stream)),
|
||||||
|
Err(e) => log::error!(
|
||||||
|
"Can not initialize stream handler for {:?} err: {}",
|
||||||
|
sig,
|
||||||
|
e
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Signals { srv, streams }
|
actix_rt::spawn(Signals { srv, streams })
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -81,7 +90,7 @@ impl Future for Signals {
|
|||||||
{
|
{
|
||||||
for idx in 0..self.streams.len() {
|
for idx in 0..self.streams.len() {
|
||||||
loop {
|
loop {
|
||||||
match Pin::new(&mut self.streams[idx].1).poll_next(cx) {
|
match self.streams[idx].1.poll_recv(cx) {
|
||||||
Poll::Ready(None) => return Poll::Ready(()),
|
Poll::Ready(None) => return Poll::Ready(()),
|
||||||
Poll::Pending => break,
|
Poll::Pending => break,
|
||||||
Poll::Ready(Some(_)) => {
|
Poll::Ready(Some(_)) => {
|
||||||
|
@ -3,8 +3,6 @@ use std::{fmt, io, net};
|
|||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_codec::{AsyncRead, AsyncWrite};
|
||||||
use actix_rt::net::TcpStream;
|
use actix_rt::net::TcpStream;
|
||||||
|
|
||||||
use tokio_net::driver::Handle;
|
|
||||||
|
|
||||||
pub(crate) enum StdListener {
|
pub(crate) enum StdListener {
|
||||||
Tcp(net::TcpListener),
|
Tcp(net::TcpListener),
|
||||||
#[cfg(all(unix))]
|
#[cfg(all(unix))]
|
||||||
@ -152,7 +150,7 @@ pub trait FromStream: AsyncRead + AsyncWrite + Sized {
|
|||||||
impl FromStream for TcpStream {
|
impl FromStream for TcpStream {
|
||||||
fn from_stdstream(sock: StdStream) -> io::Result<Self> {
|
fn from_stdstream(sock: StdStream) -> io::Result<Self> {
|
||||||
match sock {
|
match sock {
|
||||||
StdStream::Tcp(stream) => TcpStream::from_std(stream, &Handle::default()),
|
StdStream::Tcp(stream) => TcpStream::from_std(stream),
|
||||||
#[cfg(all(unix))]
|
#[cfg(all(unix))]
|
||||||
StdStream::Uds(_) => {
|
StdStream::Uds(_) => {
|
||||||
panic!("Should not happen, bug in server impl");
|
panic!("Should not happen, bug in server impl");
|
||||||
@ -166,9 +164,7 @@ impl FromStream for actix_rt::net::UnixStream {
|
|||||||
fn from_stdstream(sock: StdStream) -> io::Result<Self> {
|
fn from_stdstream(sock: StdStream) -> io::Result<Self> {
|
||||||
match sock {
|
match sock {
|
||||||
StdStream::Tcp(_) => panic!("Should not happen, bug in server impl"),
|
StdStream::Tcp(_) => panic!("Should not happen, bug in server impl"),
|
||||||
StdStream::Uds(stream) => {
|
StdStream::Uds(stream) => actix_rt::net::UnixStream::from_std(stream),
|
||||||
actix_rt::net::UnixStream::from_std(stream, &Handle::default())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,10 @@ use std::sync::Arc;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
use actix_rt::time::{delay, Delay};
|
use actix_rt::time::{delay_until, Delay, Instant};
|
||||||
use actix_rt::{spawn, Arbiter};
|
use actix_rt::{spawn, Arbiter};
|
||||||
use actix_utils::counter::Counter;
|
use actix_utils::counter::Counter;
|
||||||
use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
|
use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
|
||||||
use futures::channel::oneshot;
|
use futures::channel::oneshot;
|
||||||
use futures::future::{join_all, LocalBoxFuture, MapOk};
|
use futures::future::{join_all, LocalBoxFuture, MapOk};
|
||||||
use futures::{Future, FutureExt, Stream, TryFutureExt};
|
use futures::{Future, FutureExt, Stream, TryFutureExt};
|
||||||
@ -161,56 +161,66 @@ enum WorkerServiceStatus {
|
|||||||
|
|
||||||
impl Worker {
|
impl Worker {
|
||||||
pub(crate) fn start(
|
pub(crate) fn start(
|
||||||
rx: UnboundedReceiver<WorkerCommand>,
|
idx: usize,
|
||||||
rx2: UnboundedReceiver<StopCommand>,
|
|
||||||
factories: Vec<Box<dyn InternalServiceFactory>>,
|
factories: Vec<Box<dyn InternalServiceFactory>>,
|
||||||
availability: WorkerAvailability,
|
availability: WorkerAvailability,
|
||||||
shutdown_timeout: time::Duration,
|
shutdown_timeout: time::Duration,
|
||||||
) {
|
) -> WorkerClient {
|
||||||
availability.set(false);
|
let (tx1, rx) = unbounded();
|
||||||
let mut wrk = MAX_CONNS_COUNTER.with(|conns| Worker {
|
let (tx2, rx2) = unbounded();
|
||||||
rx,
|
let avail = availability.clone();
|
||||||
rx2,
|
|
||||||
availability,
|
|
||||||
factories,
|
|
||||||
shutdown_timeout,
|
|
||||||
services: Vec::new(),
|
|
||||||
conns: conns.clone(),
|
|
||||||
state: WorkerState::Unavailable(Vec::new()),
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut fut: Vec<MapOk<LocalBoxFuture<'static, _>, _>> = Vec::new();
|
Arbiter::new().send(
|
||||||
for (idx, factory) in wrk.factories.iter().enumerate() {
|
async move {
|
||||||
fut.push(factory.create().map_ok(move |r| {
|
availability.set(false);
|
||||||
r.into_iter()
|
let mut wrk = MAX_CONNS_COUNTER.with(move |conns| Worker {
|
||||||
.map(|(t, s): (Token, _)| (idx, t, s))
|
rx,
|
||||||
.collect::<Vec<_>>()
|
rx2,
|
||||||
}));
|
availability,
|
||||||
}
|
factories,
|
||||||
|
shutdown_timeout,
|
||||||
|
services: Vec::new(),
|
||||||
|
conns: conns.clone(),
|
||||||
|
state: WorkerState::Unavailable(Vec::new()),
|
||||||
|
});
|
||||||
|
|
||||||
spawn(async move {
|
let mut fut: Vec<MapOk<LocalBoxFuture<'static, _>, _>> = Vec::new();
|
||||||
let res = join_all(fut).await;
|
for (idx, factory) in wrk.factories.iter().enumerate() {
|
||||||
let res: Result<Vec<_>, _> = res.into_iter().collect();
|
fut.push(factory.create().map_ok(move |r| {
|
||||||
match res {
|
r.into_iter()
|
||||||
Ok(services) => {
|
.map(|(t, s): (Token, _)| (idx, t, s))
|
||||||
for item in services {
|
.collect::<Vec<_>>()
|
||||||
for (factory, token, service) in item {
|
}));
|
||||||
assert_eq!(token.0, wrk.services.len());
|
}
|
||||||
wrk.services.push(WorkerService {
|
|
||||||
factory,
|
spawn(async move {
|
||||||
service,
|
let res = join_all(fut).await;
|
||||||
status: WorkerServiceStatus::Unavailable,
|
let res: Result<Vec<_>, _> = res.into_iter().collect();
|
||||||
});
|
match res {
|
||||||
|
Ok(services) => {
|
||||||
|
for item in services {
|
||||||
|
for (factory, token, service) in item {
|
||||||
|
assert_eq!(token.0, wrk.services.len());
|
||||||
|
wrk.services.push(WorkerService {
|
||||||
|
factory,
|
||||||
|
service,
|
||||||
|
status: WorkerServiceStatus::Unavailable,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Can not start worker: {:?}", e);
|
||||||
|
Arbiter::current().stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
wrk.await
|
||||||
Err(e) => {
|
});
|
||||||
error!("Can not start worker: {:?}", e);
|
|
||||||
Arbiter::current().stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
wrk.await
|
.boxed(),
|
||||||
});
|
);
|
||||||
|
|
||||||
|
WorkerClient::new(idx, tx1, tx2, avail)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shutdown(&mut self, force: bool) {
|
fn shutdown(&mut self, force: bool) {
|
||||||
@ -322,8 +332,8 @@ impl Future for Worker {
|
|||||||
if num != 0 {
|
if num != 0 {
|
||||||
info!("Graceful worker shutdown, {} connections", num);
|
info!("Graceful worker shutdown, {} connections", num);
|
||||||
self.state = WorkerState::Shutdown(
|
self.state = WorkerState::Shutdown(
|
||||||
Box::pin(delay(time::Instant::now() + time::Duration::from_secs(1))),
|
Box::pin(delay_until(Instant::now() + time::Duration::from_secs(1))),
|
||||||
Box::pin(delay(time::Instant::now() + self.shutdown_timeout)),
|
Box::pin(delay_until(Instant::now() + self.shutdown_timeout)),
|
||||||
Some(result),
|
Some(result),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -399,7 +409,6 @@ impl Future for Worker {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
Poll::Pending => {
|
Poll::Pending => {
|
||||||
// self.state = WorkerState::Restarting(idx, token, fut);
|
|
||||||
return Poll::Pending;
|
return Poll::Pending;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -428,19 +437,18 @@ impl Future for Worker {
|
|||||||
match t1.as_mut().poll(cx) {
|
match t1.as_mut().poll(cx) {
|
||||||
Poll::Pending => (),
|
Poll::Pending => (),
|
||||||
Poll::Ready(_) => {
|
Poll::Ready(_) => {
|
||||||
*t1 = Box::pin(delay(
|
*t1 = Box::pin(delay_until(
|
||||||
time::Instant::now() + time::Duration::from_secs(1),
|
Instant::now() + time::Duration::from_secs(1),
|
||||||
));
|
));
|
||||||
let _ = t1.as_mut().poll(cx);
|
let _ = t1.as_mut().poll(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// self.state = WorkerState::Shutdown(t1, t2, tx);
|
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
WorkerState::Available => {
|
WorkerState::Available => {
|
||||||
loop {
|
loop {
|
||||||
match Pin::new(&mut self.rx).poll_next(cx) {
|
match Pin::new(&mut self.rx).poll_next(cx) {
|
||||||
// handle incoming tcp stream
|
// handle incoming io stream
|
||||||
Poll::Ready(Some(WorkerCommand(msg))) => {
|
Poll::Ready(Some(WorkerCommand(msg))) => {
|
||||||
match self.check_readiness(cx) {
|
match self.check_readiness(cx) {
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
|
@ -29,6 +29,8 @@ fn test_bind() {
|
|||||||
let h = thread::spawn(move || {
|
let h = thread::spawn(move || {
|
||||||
let sys = actix_rt::System::new("test");
|
let sys = actix_rt::System::new("test");
|
||||||
let srv = Server::build()
|
let srv = Server::build()
|
||||||
|
.workers(1)
|
||||||
|
.disable_signals()
|
||||||
.bind("test", addr, move || service_fn(|_| ok::<_, ()>(())))
|
.bind("test", addr, move || service_fn(|_| ok::<_, ()>(())))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.start();
|
.start();
|
||||||
@ -51,14 +53,16 @@ fn test_listen() {
|
|||||||
let h = thread::spawn(move || {
|
let h = thread::spawn(move || {
|
||||||
let sys = actix_rt::System::new("test");
|
let sys = actix_rt::System::new("test");
|
||||||
let lst = net::TcpListener::bind(addr).unwrap();
|
let lst = net::TcpListener::bind(addr).unwrap();
|
||||||
let srv = Server::build()
|
Server::build()
|
||||||
|
.disable_signals()
|
||||||
|
.workers(1)
|
||||||
.listen("test", lst, move || service_fn(|_| ok::<_, ()>(())))
|
.listen("test", lst, move || service_fn(|_| ok::<_, ()>(())))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.start();
|
.start();
|
||||||
let _ = tx.send((srv, actix_rt::System::current()));
|
let _ = tx.send(actix_rt::System::current());
|
||||||
let _ = sys.run();
|
let _ = sys.run();
|
||||||
});
|
});
|
||||||
let (_, sys) = rx.recv().unwrap();
|
let sys = rx.recv().unwrap();
|
||||||
|
|
||||||
thread::sleep(time::Duration::from_millis(500));
|
thread::sleep(time::Duration::from_millis(500));
|
||||||
assert!(net::TcpStream::connect(addr).is_ok());
|
assert!(net::TcpStream::connect(addr).is_ok());
|
||||||
@ -72,10 +76,12 @@ fn test_start() {
|
|||||||
let addr = unused_addr();
|
let addr = unused_addr();
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
|
||||||
let h = thread::spawn(move || {
|
let _ = thread::spawn(move || {
|
||||||
let sys = actix_rt::System::new("test");
|
let sys = actix_rt::System::new("test");
|
||||||
let srv: Server = Server::build()
|
let srv: Server = Server::build()
|
||||||
.backlog(100)
|
.backlog(100)
|
||||||
|
.workers(1)
|
||||||
|
.disable_signals()
|
||||||
.bind("test", addr, move || {
|
.bind("test", addr, move || {
|
||||||
service_fn(|io: TcpStream| {
|
service_fn(|io: TcpStream| {
|
||||||
async move {
|
async move {
|
||||||
@ -126,7 +132,7 @@ fn test_start() {
|
|||||||
|
|
||||||
thread::sleep(time::Duration::from_millis(100));
|
thread::sleep(time::Duration::from_millis(100));
|
||||||
let _ = sys.stop();
|
let _ = sys.stop();
|
||||||
let _ = h.join();
|
// let _ = h.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -142,6 +148,7 @@ fn test_configure() {
|
|||||||
let num = num2.clone();
|
let num = num2.clone();
|
||||||
let sys = actix_rt::System::new("test");
|
let sys = actix_rt::System::new("test");
|
||||||
let srv = Server::build()
|
let srv = Server::build()
|
||||||
|
.disable_signals()
|
||||||
.configure(move |cfg| {
|
.configure(move |cfg| {
|
||||||
let num = num.clone();
|
let num = num.clone();
|
||||||
let lst = net::TcpListener::bind(addr3).unwrap();
|
let lst = net::TcpListener::bind(addr3).unwrap();
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
## [1.0.0-alpha.3] - 2019-12-xx
|
||||||
|
|
||||||
|
* Migrate to `tokio=0.2.2`
|
||||||
|
|
||||||
## [1.0.0-alpha.2] - 2019-12-02
|
## [1.0.0-alpha.2] - 2019-12-02
|
||||||
|
|
||||||
* Re-export `test` attribute macros
|
* Re-export `test` attribute macros
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-testing"
|
name = "actix-testing"
|
||||||
version = "1.0.0-alpha.2"
|
version = "1.0.0-alpha.3"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix testing utils"
|
description = "Actix testing utils"
|
||||||
keywords = ["network", "framework", "async", "futures"]
|
keywords = ["network", "framework", "async", "futures"]
|
||||||
@ -17,13 +17,11 @@ name = "actix_testing"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-rt = "1.0.0-alpha.2"
|
actix-rt = "1.0.0-alpha.3"
|
||||||
actix-macros = "0.1.0-alpha.1"
|
actix-macros = "0.1.0-alpha.1"
|
||||||
actix-server = "1.0.0-alpha.2"
|
actix-server = "1.0.0-alpha.3"
|
||||||
actix-service = "1.0.0-alpha.3"
|
actix-service = "1.0.0-alpha.3"
|
||||||
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
net2 = "0.2"
|
net2 = "0.2"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
|
|
||||||
tokio-net = { version = "=0.2.0-alpha.6" }
|
|
||||||
|
@ -7,9 +7,7 @@ use std::{net, thread};
|
|||||||
|
|
||||||
use actix_rt::{net::TcpStream, System};
|
use actix_rt::{net::TcpStream, System};
|
||||||
use actix_server::{Server, ServerBuilder, ServiceFactory};
|
use actix_server::{Server, ServerBuilder, ServiceFactory};
|
||||||
|
|
||||||
use net2::TcpBuilder;
|
use net2::TcpBuilder;
|
||||||
use tokio_net::driver::Handle;
|
|
||||||
|
|
||||||
#[cfg(not(test))] // Work around for rust-lang/rust#62127
|
#[cfg(not(test))] // Work around for rust-lang/rust#62127
|
||||||
pub use actix_macros::test;
|
pub use actix_macros::test;
|
||||||
@ -25,7 +23,8 @@ pub use actix_macros::test;
|
|||||||
/// use actix_service::{service_fn};
|
/// use actix_service::{service_fn};
|
||||||
/// use actix_testing::TestServer;
|
/// use actix_testing::TestServer;
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// #[actix_rt::main]
|
||||||
|
/// async fn main() {
|
||||||
/// let srv = TestServer::with(|| service_fn(
|
/// let srv = TestServer::with(|| service_fn(
|
||||||
/// |sock| async move {
|
/// |sock| async move {
|
||||||
/// println!("New connection: {:?}", sock);
|
/// println!("New connection: {:?}", sock);
|
||||||
@ -142,7 +141,7 @@ impl TestServerRuntime {
|
|||||||
|
|
||||||
/// Connect to server, return tokio TcpStream
|
/// Connect to server, return tokio TcpStream
|
||||||
pub fn connect(&self) -> std::io::Result<TcpStream> {
|
pub fn connect(&self) -> std::io::Result<TcpStream> {
|
||||||
TcpStream::from_std(net::TcpStream::connect(self.addr)?, &Handle::default())
|
TcpStream::from_std(net::TcpStream::connect(self.addr)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
[1.0.0-alpha.3] - 2019-12-xx
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Migrate to `tokio=0.2.2`
|
||||||
|
|
||||||
|
* Enable rustls acceptor service
|
||||||
|
|
||||||
## [1.0.0-alpha.1] - 2019-12-02
|
## [1.0.0-alpha.1] - 2019-12-02
|
||||||
|
|
||||||
* Split openssl accetor from actix-server package
|
* Split openssl accetor from actix-server package
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-tls"
|
name = "actix-tls"
|
||||||
version = "1.0.0-alpha.1"
|
version = "1.0.0-alpha.3"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix tls services"
|
description = "Actix tls services"
|
||||||
keywords = ["network", "framework", "async", "futures"]
|
keywords = ["network", "framework", "async", "futures"]
|
||||||
@ -30,9 +30,9 @@ rustls = ["rust-tls", "webpki"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-service = "1.0.0-alpha.3"
|
actix-service = "1.0.0-alpha.3"
|
||||||
actix-codec = "0.2.0-alpha.2"
|
actix-codec = "0.2.0-alpha.3"
|
||||||
actix-utils = "1.0.0-alpha.2"
|
actix-utils = "1.0.0-alpha.3"
|
||||||
actix-rt = "1.0.0-alpha.2"
|
actix-rt = "1.0.0-alpha.3"
|
||||||
derive_more = "0.99.2"
|
derive_more = "0.99.2"
|
||||||
either = "1.5.2"
|
either = "1.5.2"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
@ -40,15 +40,14 @@ log = "0.4"
|
|||||||
|
|
||||||
# openssl
|
# openssl
|
||||||
open-ssl = { version="0.10", package = "openssl", optional = true }
|
open-ssl = { version="0.10", package = "openssl", optional = true }
|
||||||
tokio-openssl = { version = "=0.4.0-alpha.6", optional = true }
|
tokio-openssl = { version = "0.4.0", optional = true }
|
||||||
|
|
||||||
# rustls
|
# rustls
|
||||||
rust-tls = { version = "0.16.0", package = "rustls", optional = true }
|
rust-tls = { version = "0.16.0", package = "rustls", optional = true }
|
||||||
webpki = { version = "0.21", optional = true }
|
webpki = { version = "0.21", optional = true }
|
||||||
webpki-roots = { version = "0.17", optional = true }
|
webpki-roots = { version = "0.17", optional = true }
|
||||||
# tokio-rustls = { version = "0.12.0-alpha.2", optional = true }
|
tokio-rustls = { version = "0.12.0", optional = true }
|
||||||
# tokio-rustls = { git = "https://github.com/quininer/tokio-rustls.git", branch = "tokio-0.2", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
bytes = "0.4"
|
bytes = "0.5"
|
||||||
actix-testing = { version="1.0.0-alpha.2" }
|
actix-testing = { version="1.0.0-alpha.3" }
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## [1.0.0-alpha.3] - 2019-12-xx
|
## [1.0.0-alpha.3] - 2019-12-xx
|
||||||
|
|
||||||
|
* Migrate to `tokio=0.2.2`
|
||||||
|
|
||||||
* Fix oneshot
|
* Fix oneshot
|
||||||
|
|
||||||
## [1.0.0-alpha.2] - 2019-12-02
|
## [1.0.0-alpha.2] - 2019-12-02
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-utils"
|
name = "actix-utils"
|
||||||
version = "1.0.0-alpha.2"
|
version = "1.0.0-alpha.3"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix utils - various actix net related services"
|
description = "Actix utils - various actix net related services"
|
||||||
keywords = ["network", "framework", "async", "futures"]
|
keywords = ["network", "framework", "async", "futures"]
|
||||||
@ -19,9 +19,9 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-service = "1.0.0-alpha.3"
|
actix-service = "1.0.0-alpha.3"
|
||||||
actix-rt = "1.0.0-alpha.2"
|
actix-rt = "1.0.0-alpha.3"
|
||||||
actix-codec = "0.2.0-alpha.2"
|
actix-codec = "0.2.0-alpha.3"
|
||||||
bytes = "0.4"
|
bytes = "0.5.2"
|
||||||
either = "1.5.2"
|
either = "1.5.2"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
pin-project = "0.4.6"
|
pin-project = "0.4.6"
|
||||||
|
@ -3,9 +3,9 @@ use std::future::Future;
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::Duration;
|
||||||
|
|
||||||
use actix_rt::time::{delay, Delay};
|
use actix_rt::time::{delay_until, Delay, Instant};
|
||||||
use actix_service::{Service, ServiceFactory};
|
use actix_service::{Service, ServiceFactory};
|
||||||
use futures::future::{ok, Ready};
|
use futures::future::{ok, Ready};
|
||||||
|
|
||||||
@ -81,13 +81,13 @@ where
|
|||||||
F: Fn() -> E,
|
F: Fn() -> E,
|
||||||
{
|
{
|
||||||
pub fn new(ka: Duration, time: LowResTimeService, f: F) -> Self {
|
pub fn new(ka: Duration, time: LowResTimeService, f: F) -> Self {
|
||||||
let expire = time.now() + ka;
|
let expire = Instant::from_std(time.now() + ka);
|
||||||
KeepAliveService {
|
KeepAliveService {
|
||||||
f,
|
f,
|
||||||
ka,
|
ka,
|
||||||
time,
|
time,
|
||||||
expire,
|
expire,
|
||||||
delay: delay(expire),
|
delay: delay_until(expire),
|
||||||
_t: PhantomData,
|
_t: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ where
|
|||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
match Pin::new(&mut self.delay).poll(cx) {
|
match Pin::new(&mut self.delay).poll(cx) {
|
||||||
Poll::Ready(_) => {
|
Poll::Ready(_) => {
|
||||||
let now = self.time.now();
|
let now = Instant::from_std(self.time.now());
|
||||||
if self.expire <= now {
|
if self.expire <= now {
|
||||||
Poll::Ready(Err((self.f)()))
|
Poll::Ready(Err((self.f)()))
|
||||||
} else {
|
} else {
|
||||||
@ -119,7 +119,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: R) -> Self::Future {
|
fn call(&mut self, req: R) -> Self::Future {
|
||||||
self.expire = self.time.now() + self.ka;
|
self.expire = Instant::from_std(self.time.now() + self.ka);
|
||||||
ok(req)
|
ok(req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
## [0.2.0] - 2019-12-05
|
||||||
|
|
||||||
|
* Update http to 0.2
|
||||||
|
|
||||||
|
* Update regex to 1.3
|
||||||
|
|
||||||
## [0.1.5] - 2019-05-15
|
## [0.1.5] - 2019-05-15
|
||||||
|
|
||||||
* Remove debug prints
|
* Remove debug prints
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-router"
|
name = "actix-router"
|
||||||
version = "0.1.5"
|
version = "0.2.0"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Path router"
|
description = "Path router"
|
||||||
keywords = ["actix"]
|
keywords = ["actix"]
|
||||||
@ -20,13 +20,12 @@ path = "src/lib.rs"
|
|||||||
default = ["http"]
|
default = ["http"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bytes = "0.4"
|
regex = "1.3.1"
|
||||||
regex = "1.0"
|
|
||||||
serde = "1.0.80"
|
serde = "1.0.80"
|
||||||
string = "0.2.0"
|
string = "0.2.1"
|
||||||
log = "0.4"
|
log = "0.4.8"
|
||||||
http = { version="0.1.14", optional=true }
|
http = { version="0.2.0", optional=true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
http = "0.1.14"
|
http = "0.2.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
@ -491,7 +491,8 @@ pub(crate) fn insert_slash(path: &str) -> String {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use http::{HttpTryFrom, Uri};
|
use http::Uri;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_static() {
|
fn test_parse_static() {
|
||||||
|
@ -200,7 +200,8 @@ fn restore_ch(d1: u8, d2: u8) -> Option<u8> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use http::{HttpTryFrom, Uri};
|
use http::Uri;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{Path, ResourceDef};
|
use crate::{Path, ResourceDef};
|
||||||
|
Loading…
Reference in New Issue
Block a user