mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-23 22:51:07 +01:00
migrate to tokio 0.2.2
This commit is contained in:
parent
d49aca9595
commit
3a858feaec
@ -1,5 +1,11 @@
|
||||
# Changes
|
||||
|
||||
## [1.0.0-alpha.3] - 2019-12-xx
|
||||
|
||||
### Changed
|
||||
|
||||
* Migrate to `tokio=0.2.2`
|
||||
|
||||
## [1.0.0-alpha.2] - 2019-12-02
|
||||
|
||||
### Changed
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-connect"
|
||||
version = "1.0.0-alpha.2"
|
||||
version = "1.0.0-alpha.3"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix connect - tcp connector service"
|
||||
keywords = ["network", "framework", "async", "futures"]
|
||||
@ -27,33 +27,33 @@ default = ["uri"]
|
||||
openssl = ["open-ssl", "tokio-openssl"]
|
||||
|
||||
# rustls
|
||||
# rustls = ["rust-tls", "tokio-rustls", "webpki"]
|
||||
rustls = ["rust-tls", "tokio-rustls", "webpki"]
|
||||
|
||||
# support http::Uri as connect address
|
||||
uri = ["http"]
|
||||
|
||||
[dependencies]
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-codec = "0.2.0-alpha.2"
|
||||
actix-utils = "1.0.0-alpha.2"
|
||||
actix-rt = "1.0.0-alpha.2"
|
||||
actix-codec = "0.2.0-alpha.3"
|
||||
actix-utils = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
derive_more = "0.99.2"
|
||||
either = "1.5.2"
|
||||
futures = "0.3.1"
|
||||
http = { version = "0.1.17", optional = true }
|
||||
http = { version = "0.2.0", optional = true }
|
||||
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
|
||||
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
|
||||
rust-tls = { version = "0.16.0", package = "rustls", optional = true }
|
||||
# tokio-rustls = { version = "0.10.0", optional = true }
|
||||
# tokio-rustls = { git = "https://github.com/quininer/tokio-rustls.git", branch = "tokio-0.2", optional = true }
|
||||
tokio-rustls = { version = "0.12.0", optional = true }
|
||||
webpki = { version = "0.21", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
bytes = "0.4"
|
||||
bytes = "0.5.2"
|
||||
actix-testing = { version="1.0.0-alpha.2" }
|
||||
|
@ -14,7 +14,7 @@ extern crate log;
|
||||
mod connect;
|
||||
mod connector;
|
||||
mod error;
|
||||
mod resolver;
|
||||
mod resolve;
|
||||
mod service;
|
||||
pub mod ssl;
|
||||
|
||||
@ -23,15 +23,20 @@ mod uri;
|
||||
|
||||
use actix_rt::{net::TcpStream, Arbiter};
|
||||
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 use trust_dns_resolver::system_conf::read_system_conf;
|
||||
pub use trust_dns_resolver::{error::ResolveError, AsyncResolver};
|
||||
pub mod resolver {
|
||||
pub use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
|
||||
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::connector::{TcpConnector, TcpConnectorFactory};
|
||||
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 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::connector::{TcpConnector, TcpConnectorFactory};
|
||||
use crate::error::ConnectError;
|
||||
use crate::resolver::{Resolver, ResolverFactory};
|
||||
use crate::resolve::{Resolver, ResolverFactory};
|
||||
|
||||
pub struct ConnectServiceFactory<T> {
|
||||
tcp: TcpConnectorFactory<T>,
|
||||
|
@ -62,7 +62,7 @@ where
|
||||
type InitError = ();
|
||||
type Future = Ready<Result<Self::Service, Self::InitError>>;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
fn new_service(&self, _: ()) -> Self::Future {
|
||||
ok(RustlsConnectorService {
|
||||
connector: self.connector.clone(),
|
||||
_t: PhantomData,
|
||||
@ -93,7 +93,7 @@ where
|
||||
type Error = std::io::Error;
|
||||
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(()))
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ where
|
||||
{
|
||||
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();
|
||||
Poll::Ready(
|
||||
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 bytes::Bytes;
|
||||
use futures::SinkExt;
|
||||
use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
|
||||
|
||||
use actix_connect::resolver::{ResolverConfig, ResolverOpts};
|
||||
use actix_connect::Connect;
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
@ -97,7 +97,7 @@ async fn test_new_service() {
|
||||
#[cfg(feature = "openssl")]
|
||||
#[actix_rt::test]
|
||||
async fn test_uri() {
|
||||
use http::HttpTryFrom;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
let srv = TestServer::with(|| {
|
||||
service_fn(|io: TcpStream| {
|
||||
@ -118,7 +118,7 @@ async fn test_uri() {
|
||||
#[cfg(feature = "rustls")]
|
||||
#[actix_rt::test]
|
||||
async fn test_rustls_uri() {
|
||||
use http::HttpTryFrom;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
let srv = TestServer::with(|| {
|
||||
service_fn(|io: TcpStream| {
|
||||
|
@ -1,15 +1,17 @@
|
||||
# Changes
|
||||
|
||||
## [0.3.0-alpha.3] - 2019-12-xx
|
||||
|
||||
* Migrate to `tokio=0.2.2`
|
||||
|
||||
## [0.3.0-alpha.2] - 2019-12-02
|
||||
|
||||
* Migrate to `std::future`
|
||||
|
||||
|
||||
## [0.1.1] - 2019-10-14
|
||||
|
||||
* Re-register task on every dispatcher poll.
|
||||
|
||||
|
||||
## [0.1.0] - 2019-09-25
|
||||
|
||||
* Initial release
|
||||
|
@ -22,7 +22,7 @@ actix-service = "1.0.0-alpha.3"
|
||||
actix-codec = "0.2.0-alpha.2"
|
||||
actix-utils = "1.0.0-alpha.2"
|
||||
actix-rt = "1.0.0-alpha.2"
|
||||
bytes = "0.4"
|
||||
bytes = "0.5"
|
||||
either = "1.5.2"
|
||||
futures = "0.3.1"
|
||||
pin-project = "0.4.6"
|
||||
|
@ -6,6 +6,10 @@
|
||||
|
||||
* Fix compilation on non-unix platforms
|
||||
|
||||
### Changed
|
||||
|
||||
* Migrate to `tokio=0.2.2`
|
||||
|
||||
|
||||
## [1.0.0-alpha.2] - 2019-12-02
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-rt"
|
||||
version = "1.0.0-alpha.2"
|
||||
version = "1.0.0-alpha.3"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix runtime"
|
||||
keywords = ["network", "framework", "async", "futures"]
|
||||
@ -22,8 +22,4 @@ actix-macros = "0.1.0-alpha.1"
|
||||
actix-threadpool = "0.3"
|
||||
futures = "0.3.1"
|
||||
copyless = "0.1.4"
|
||||
|
||||
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"
|
||||
tokio = { version = "0.2.2", default-features=false, features=["rt-core", "rt-util", "io-driver", "tcp", "uds", "udp", "time", "signal"] }
|
||||
|
@ -9,9 +9,8 @@ use std::{fmt, thread};
|
||||
use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
|
||||
use futures::channel::oneshot::{channel, Canceled, Sender};
|
||||
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 copyless::BoxHelper;
|
||||
@ -19,7 +18,7 @@ use copyless::BoxHelper;
|
||||
thread_local!(
|
||||
static ADDR: RefCell<Option<Arbiter>> = RefCell::new(None);
|
||||
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());
|
||||
);
|
||||
|
||||
@ -101,7 +100,7 @@ impl Arbiter {
|
||||
let handle = thread::Builder::new()
|
||||
.name(name.clone())
|
||||
.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 (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));
|
||||
Q.with(|cell| {
|
||||
let mut v = cell.borrow_mut();
|
||||
for fut in v.drain(..) {
|
||||
// We pin the boxed future, so it can never again be moved.
|
||||
let fut = unsafe { Pin::new_unchecked(fut) };
|
||||
tokio_executor::current_thread::spawn(fut);
|
||||
if let Some(rt) = rt {
|
||||
rt.spawn(fut);
|
||||
} else {
|
||||
tokio::task::spawn_local(fut);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -169,11 +170,14 @@ impl Arbiter {
|
||||
RUNNING.with(move |cell| {
|
||||
if cell.get() {
|
||||
// Spawn the future on running executor
|
||||
spawn(future);
|
||||
tokio::task::spawn_local(future);
|
||||
} else {
|
||||
// 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
|
||||
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(());
|
||||
}
|
||||
ArbiterCommand::Execute(fut) => {
|
||||
spawn(fut);
|
||||
tokio::task::spawn_local(fut);
|
||||
}
|
||||
ArbiterCommand::ExecuteFn(f) => {
|
||||
f.call_box();
|
||||
|
@ -4,11 +4,7 @@ use std::io;
|
||||
use futures::channel::mpsc::unbounded;
|
||||
use futures::channel::oneshot::{channel, Receiver};
|
||||
use futures::future::{lazy, Future, FutureExt};
|
||||
|
||||
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 tokio::task::LocalSet;
|
||||
|
||||
use crate::arbiter::{Arbiter, SystemArbiter};
|
||||
use crate::runtime::Runtime;
|
||||
@ -23,9 +19,6 @@ pub struct Builder {
|
||||
/// Name of the System. Defaults to "actix" if unset.
|
||||
name: Cow<'static, str>,
|
||||
|
||||
/// The clock to use
|
||||
clock: Clock,
|
||||
|
||||
/// Whether the Arbiter will stop the whole System on uncaught panic. Defaults to false.
|
||||
stop_on_panic: bool,
|
||||
}
|
||||
@ -34,7 +27,6 @@ impl Builder {
|
||||
pub(crate) fn new() -> Self {
|
||||
Builder {
|
||||
name: Cow::Borrowed("actix"),
|
||||
clock: Clock::new(),
|
||||
stop_on_panic: false,
|
||||
}
|
||||
}
|
||||
@ -45,14 +37,6 @@ impl Builder {
|
||||
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
|
||||
/// uncaught panic is thrown from a worker thread.
|
||||
///
|
||||
@ -72,8 +56,8 @@ impl Builder {
|
||||
/// Create new System that can run asynchronously.
|
||||
///
|
||||
/// This method panics if it cannot start the system arbiter
|
||||
pub(crate) fn build_async(self, executor: Handle) -> AsyncSystemRunner {
|
||||
self.create_async_runtime(executor)
|
||||
pub(crate) fn build_async(self, local: &LocalSet) -> AsyncSystemRunner {
|
||||
self.create_async_runtime(local)
|
||||
}
|
||||
|
||||
/// This function will start tokio runtime and will finish once the
|
||||
@ -86,7 +70,7 @@ impl Builder {
|
||||
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 (sys_sender, sys_receiver) = unbounded();
|
||||
|
||||
@ -96,7 +80,7 @@ impl Builder {
|
||||
let arb = SystemArbiter::new(stop_tx, sys_receiver);
|
||||
|
||||
// start the system arbiter
|
||||
executor.spawn(arb).expect("could not start system arbiter");
|
||||
let _ = local.spawn_local(arb);
|
||||
|
||||
AsyncSystemRunner { stop, system }
|
||||
}
|
||||
@ -113,40 +97,14 @@ impl Builder {
|
||||
// system arbiter
|
||||
let arb = SystemArbiter::new(stop_tx, sys_receiver);
|
||||
|
||||
let mut rt = self.build_rt().unwrap();
|
||||
let mut rt = Runtime::new().unwrap();
|
||||
rt.spawn(arb);
|
||||
|
||||
// init system arbiter and run configuration method
|
||||
let _ = rt.block_on(lazy(move |_| {
|
||||
f();
|
||||
Ok::<_, ()>(())
|
||||
}));
|
||||
rt.block_on(lazy(move |_| f()));
|
||||
|
||||
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)]
|
||||
@ -163,7 +121,7 @@ impl AsyncSystemRunner {
|
||||
|
||||
// run loop
|
||||
lazy(|_| {
|
||||
Arbiter::run_system();
|
||||
Arbiter::run_system(None);
|
||||
async {
|
||||
let res = match stop.await {
|
||||
Ok(code) => {
|
||||
@ -202,10 +160,7 @@ impl SystemRunner {
|
||||
let SystemRunner { mut rt, stop, .. } = self;
|
||||
|
||||
// run loop
|
||||
let _ = rt.block_on(async {
|
||||
Arbiter::run_system();
|
||||
Ok::<_, ()>(())
|
||||
});
|
||||
Arbiter::run_system(Some(&rt));
|
||||
let result = match rt.block_on(stop) {
|
||||
Ok(code) => {
|
||||
if code != 0 {
|
||||
@ -226,17 +181,11 @@ impl SystemRunner {
|
||||
/// Execute a future and wait for result.
|
||||
pub fn block_on<F, O>(&mut self, fut: F) -> O
|
||||
where
|
||||
F: Future<Output = O>,
|
||||
F: Future<Output = O> + 'static,
|
||||
{
|
||||
self.rt.block_on(async {
|
||||
Arbiter::run_system();
|
||||
});
|
||||
|
||||
Arbiter::run_system(Some(&self.rt));
|
||||
let res = self.rt.block_on(fut);
|
||||
self.rt.block_on(async {
|
||||
Arbiter::stop_system();
|
||||
});
|
||||
|
||||
Arbiter::stop_system();
|
||||
res
|
||||
}
|
||||
}
|
||||
|
@ -38,9 +38,9 @@ where
|
||||
pub mod signal {
|
||||
#[cfg(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
|
||||
@ -59,21 +59,8 @@ pub mod net {
|
||||
|
||||
/// Utilities for tracking time.
|
||||
pub mod time {
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub use tokio_timer::Interval;
|
||||
pub use tokio_timer::{delay, delay_for, Delay};
|
||||
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)
|
||||
}
|
||||
pub use tokio::time::Instant;
|
||||
pub use tokio::time::{delay_for, delay_until, Delay};
|
||||
pub use tokio::time::{interval, interval_at, Interval};
|
||||
pub use tokio::time::{timeout, Timeout};
|
||||
}
|
||||
|
@ -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::{fmt, io};
|
||||
|
||||
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;
|
||||
use std::future::Future;
|
||||
use std::io;
|
||||
use tokio::{runtime, task::LocalSet};
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// [mod]: index.html
|
||||
#[derive(Debug)]
|
||||
pub struct Runtime {
|
||||
reactor_handle: ReactorHandle,
|
||||
timer_handle: timer::Handle,
|
||||
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()
|
||||
}
|
||||
local: LocalSet,
|
||||
rt: runtime::Runtime,
|
||||
}
|
||||
|
||||
impl Runtime {
|
||||
#[allow(clippy::new_ret_no_self)]
|
||||
/// Returns a new runtime initialized with default configuration values.
|
||||
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(
|
||||
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.
|
||||
/// Spawn a future onto the single-threaded runtime.
|
||||
///
|
||||
/// See [module level][mod] documentation for more details.
|
||||
///
|
||||
@ -75,7 +38,7 @@ impl Runtime {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,ignore
|
||||
/// # use futures::{future, Future, Stream};
|
||||
/// use actix_rt::Runtime;
|
||||
///
|
||||
@ -95,11 +58,11 @@ impl Runtime {
|
||||
///
|
||||
/// This function panics if the spawn fails. Failure occurs if the executor
|
||||
/// 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
|
||||
F: Future<Output = ()> + 'static,
|
||||
{
|
||||
self.executor.spawn(future);
|
||||
self.local.spawn_local(future);
|
||||
self
|
||||
}
|
||||
|
||||
@ -121,41 +84,9 @@ impl Runtime {
|
||||
/// complete execution by calling `block_on` or `run`.
|
||||
pub fn block_on<F>(&mut self, f: F) -> F::Output
|
||||
where
|
||||
F: Future,
|
||||
F: Future + 'static,
|
||||
{
|
||||
self.enter(|executor| {
|
||||
// Run the provided future
|
||||
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)
|
||||
})
|
||||
})
|
||||
let res = self.local.block_on(&mut self.rt, f);
|
||||
res
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use std::io;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use futures::channel::mpsc::UnboundedSender;
|
||||
use tokio::runtime::current_thread::Handle;
|
||||
use tokio::task::LocalSet;
|
||||
|
||||
use crate::arbiter::{Arbiter, SystemCommand};
|
||||
use crate::builder::{Builder, SystemRunner};
|
||||
@ -58,16 +58,16 @@ impl System {
|
||||
}
|
||||
|
||||
#[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
|
||||
pub fn run_in_executor<T: Into<String>>(
|
||||
pub fn run_in_tokio<T: Into<String>>(
|
||||
name: T,
|
||||
executor: Handle,
|
||||
) -> impl Future<Output = Result<(), io::Error>> + Send {
|
||||
local: &LocalSet,
|
||||
) -> impl Future<Output = io::Result<()>> {
|
||||
Self::builder()
|
||||
.name(name)
|
||||
.build_async(executor)
|
||||
.build_async(local)
|
||||
.run_nonblocking()
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
## [1.0.0-alpha.3] - 2019-12-xx
|
||||
|
||||
### Changed
|
||||
|
||||
* Migrate to `tokio=0.2.2`
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix compilation on non-unix platforms
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-server"
|
||||
version = "1.0.0-alpha.2"
|
||||
version = "1.0.0-alpha.3"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix server - General purpose tcp server"
|
||||
keywords = ["network", "framework", "async", "futures"]
|
||||
@ -22,9 +22,9 @@ default = []
|
||||
|
||||
[dependencies]
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0-alpha.2"
|
||||
actix-codec = "0.2.0-alpha.2"
|
||||
actix-utils = "1.0.0-alpha.2"
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-codec = "0.2.0-alpha.3"
|
||||
actix-utils = "1.0.0-alpha.3"
|
||||
|
||||
log = "0.4"
|
||||
num_cpus = "1.0"
|
||||
@ -33,13 +33,10 @@ net2 = "0.2"
|
||||
futures = "0.3.1"
|
||||
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
|
||||
mio-uds = { version = "0.6.7" }
|
||||
|
||||
[dev-dependencies]
|
||||
bytes = "0.4"
|
||||
bytes = "0.5"
|
||||
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::time::{Duration, Instant};
|
||||
use std::time::Duration;
|
||||
use std::{io, thread};
|
||||
|
||||
use actix_rt::time::delay;
|
||||
use actix_rt::time::{delay_until, Instant};
|
||||
use actix_rt::System;
|
||||
use futures::FutureExt;
|
||||
use log::{error, info};
|
||||
use slab::Slab;
|
||||
|
||||
@ -440,13 +439,10 @@ impl Accept {
|
||||
info.timeout = Some(Instant::now() + Duration::from_millis(500));
|
||||
|
||||
let r = self.timer.1.clone();
|
||||
System::current().arbiter().send(
|
||||
async move {
|
||||
delay(Instant::now() + Duration::from_millis(510)).await;
|
||||
let _ = r.set_readiness(mio::Ready::readable());
|
||||
}
|
||||
.boxed(),
|
||||
);
|
||||
System::current().arbiter().send(Box::pin(async move {
|
||||
delay_until(Instant::now() + Duration::from_millis(510)).await;
|
||||
let _ = r.set_readiness(mio::Ready::readable());
|
||||
}));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
use std::time::{Duration, Instant};
|
||||
use std::time::Duration;
|
||||
use std::{io, mem, net};
|
||||
|
||||
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::oneshot;
|
||||
use futures::future::ready;
|
||||
@ -305,22 +306,11 @@ impl ServerBuilder {
|
||||
}
|
||||
|
||||
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 worker = WorkerClient::new(idx, tx1, tx2, avail.clone());
|
||||
let services: Vec<Box<dyn InternalServiceFactory>> =
|
||||
self.services.iter().map(|v| v.clone_factory()).collect();
|
||||
|
||||
Arbiter::new().send(
|
||||
async move {
|
||||
Worker::start(rx1, rx2, services, avail, timeout);
|
||||
}
|
||||
.boxed(),
|
||||
);
|
||||
|
||||
worker
|
||||
Worker::start(idx, services, avail, self.shutdown_timeout)
|
||||
}
|
||||
|
||||
fn handle_cmd(&mut self, item: ServerCommand) {
|
||||
@ -395,8 +385,10 @@ impl ServerBuilder {
|
||||
if exit {
|
||||
spawn(
|
||||
async {
|
||||
delay(Instant::now() + Duration::from_millis(300))
|
||||
.await;
|
||||
delay_until(
|
||||
Instant::now() + Duration::from_millis(300),
|
||||
)
|
||||
.await;
|
||||
System::current().stop();
|
||||
}
|
||||
.boxed(),
|
||||
@ -409,10 +401,12 @@ impl ServerBuilder {
|
||||
// we need to stop system if server was spawned
|
||||
if self.exit {
|
||||
spawn(
|
||||
delay(Instant::now() + Duration::from_millis(300)).then(|_| {
|
||||
System::current().stop();
|
||||
ready(())
|
||||
}),
|
||||
delay_until(Instant::now() + Duration::from_millis(300)).then(
|
||||
|_| {
|
||||
System::current().stop();
|
||||
ready(())
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
if let Some(tx) = completion {
|
||||
|
@ -3,7 +3,7 @@ use std::io;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use futures_core::stream::Stream;
|
||||
use futures::future::lazy;
|
||||
|
||||
use crate::server::Server;
|
||||
|
||||
@ -33,11 +33,13 @@ pub(crate) struct Signals {
|
||||
|
||||
impl Signals {
|
||||
pub(crate) fn start(srv: Server) -> io::Result<()> {
|
||||
actix_rt::spawn({
|
||||
actix_rt::spawn(lazy(|_| {
|
||||
#[cfg(not(unix))]
|
||||
{
|
||||
let stream = actix_rt::signal::ctrl_c()?;
|
||||
Signals { srv, stream }
|
||||
match actix_rt::signal::ctrl_c() {
|
||||
Ok(stream) => actix_rt::spawn(Signals { srv, stream }),
|
||||
Err(e) => log::error!("Can not initialize ctrl-c handler err: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
@ -54,12 +56,19 @@ impl Signals {
|
||||
];
|
||||
|
||||
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(())
|
||||
}
|
||||
@ -81,7 +90,7 @@ impl Future for Signals {
|
||||
{
|
||||
for idx in 0..self.streams.len() {
|
||||
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::Pending => break,
|
||||
Poll::Ready(Some(_)) => {
|
||||
|
@ -3,8 +3,6 @@ use std::{fmt, io, net};
|
||||
use actix_codec::{AsyncRead, AsyncWrite};
|
||||
use actix_rt::net::TcpStream;
|
||||
|
||||
use tokio_net::driver::Handle;
|
||||
|
||||
pub(crate) enum StdListener {
|
||||
Tcp(net::TcpListener),
|
||||
#[cfg(all(unix))]
|
||||
@ -152,7 +150,7 @@ pub trait FromStream: AsyncRead + AsyncWrite + Sized {
|
||||
impl FromStream for TcpStream {
|
||||
fn from_stdstream(sock: StdStream) -> io::Result<Self> {
|
||||
match sock {
|
||||
StdStream::Tcp(stream) => TcpStream::from_std(stream, &Handle::default()),
|
||||
StdStream::Tcp(stream) => TcpStream::from_std(stream),
|
||||
#[cfg(all(unix))]
|
||||
StdStream::Uds(_) => {
|
||||
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> {
|
||||
match sock {
|
||||
StdStream::Tcp(_) => panic!("Should not happen, bug in server impl"),
|
||||
StdStream::Uds(stream) => {
|
||||
actix_rt::net::UnixStream::from_std(stream, &Handle::default())
|
||||
}
|
||||
StdStream::Uds(stream) => actix_rt::net::UnixStream::from_std(stream),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ use std::sync::Arc;
|
||||
use std::task::{Context, Poll};
|
||||
use std::time;
|
||||
|
||||
use actix_rt::time::{delay, Delay};
|
||||
use actix_rt::time::{delay_until, Delay, Instant};
|
||||
use actix_rt::{spawn, Arbiter};
|
||||
use actix_utils::counter::Counter;
|
||||
use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
|
||||
use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
|
||||
use futures::channel::oneshot;
|
||||
use futures::future::{join_all, LocalBoxFuture, MapOk};
|
||||
use futures::{Future, FutureExt, Stream, TryFutureExt};
|
||||
@ -161,56 +161,66 @@ enum WorkerServiceStatus {
|
||||
|
||||
impl Worker {
|
||||
pub(crate) fn start(
|
||||
rx: UnboundedReceiver<WorkerCommand>,
|
||||
rx2: UnboundedReceiver<StopCommand>,
|
||||
idx: usize,
|
||||
factories: Vec<Box<dyn InternalServiceFactory>>,
|
||||
availability: WorkerAvailability,
|
||||
shutdown_timeout: time::Duration,
|
||||
) {
|
||||
availability.set(false);
|
||||
let mut wrk = MAX_CONNS_COUNTER.with(|conns| Worker {
|
||||
rx,
|
||||
rx2,
|
||||
availability,
|
||||
factories,
|
||||
shutdown_timeout,
|
||||
services: Vec::new(),
|
||||
conns: conns.clone(),
|
||||
state: WorkerState::Unavailable(Vec::new()),
|
||||
});
|
||||
) -> WorkerClient {
|
||||
let (tx1, rx) = unbounded();
|
||||
let (tx2, rx2) = unbounded();
|
||||
let avail = availability.clone();
|
||||
|
||||
let mut fut: Vec<MapOk<LocalBoxFuture<'static, _>, _>> = Vec::new();
|
||||
for (idx, factory) in wrk.factories.iter().enumerate() {
|
||||
fut.push(factory.create().map_ok(move |r| {
|
||||
r.into_iter()
|
||||
.map(|(t, s): (Token, _)| (idx, t, s))
|
||||
.collect::<Vec<_>>()
|
||||
}));
|
||||
}
|
||||
Arbiter::new().send(
|
||||
async move {
|
||||
availability.set(false);
|
||||
let mut wrk = MAX_CONNS_COUNTER.with(move |conns| Worker {
|
||||
rx,
|
||||
rx2,
|
||||
availability,
|
||||
factories,
|
||||
shutdown_timeout,
|
||||
services: Vec::new(),
|
||||
conns: conns.clone(),
|
||||
state: WorkerState::Unavailable(Vec::new()),
|
||||
});
|
||||
|
||||
spawn(async move {
|
||||
let res = join_all(fut).await;
|
||||
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,
|
||||
});
|
||||
let mut fut: Vec<MapOk<LocalBoxFuture<'static, _>, _>> = Vec::new();
|
||||
for (idx, factory) in wrk.factories.iter().enumerate() {
|
||||
fut.push(factory.create().map_ok(move |r| {
|
||||
r.into_iter()
|
||||
.map(|(t, s): (Token, _)| (idx, t, s))
|
||||
.collect::<Vec<_>>()
|
||||
}));
|
||||
}
|
||||
|
||||
spawn(async move {
|
||||
let res = join_all(fut).await;
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Can not start worker: {:?}", e);
|
||||
Arbiter::current().stop();
|
||||
}
|
||||
wrk.await
|
||||
});
|
||||
}
|
||||
wrk.await
|
||||
});
|
||||
.boxed(),
|
||||
);
|
||||
|
||||
WorkerClient::new(idx, tx1, tx2, avail)
|
||||
}
|
||||
|
||||
fn shutdown(&mut self, force: bool) {
|
||||
@ -322,8 +332,8 @@ impl Future for Worker {
|
||||
if num != 0 {
|
||||
info!("Graceful worker shutdown, {} connections", num);
|
||||
self.state = WorkerState::Shutdown(
|
||||
Box::pin(delay(time::Instant::now() + time::Duration::from_secs(1))),
|
||||
Box::pin(delay(time::Instant::now() + self.shutdown_timeout)),
|
||||
Box::pin(delay_until(Instant::now() + time::Duration::from_secs(1))),
|
||||
Box::pin(delay_until(Instant::now() + self.shutdown_timeout)),
|
||||
Some(result),
|
||||
);
|
||||
} else {
|
||||
@ -399,7 +409,6 @@ impl Future for Worker {
|
||||
);
|
||||
}
|
||||
Poll::Pending => {
|
||||
// self.state = WorkerState::Restarting(idx, token, fut);
|
||||
return Poll::Pending;
|
||||
}
|
||||
}
|
||||
@ -428,19 +437,18 @@ impl Future for Worker {
|
||||
match t1.as_mut().poll(cx) {
|
||||
Poll::Pending => (),
|
||||
Poll::Ready(_) => {
|
||||
*t1 = Box::pin(delay(
|
||||
time::Instant::now() + time::Duration::from_secs(1),
|
||||
*t1 = Box::pin(delay_until(
|
||||
Instant::now() + time::Duration::from_secs(1),
|
||||
));
|
||||
let _ = t1.as_mut().poll(cx);
|
||||
}
|
||||
}
|
||||
// self.state = WorkerState::Shutdown(t1, t2, tx);
|
||||
Poll::Pending
|
||||
}
|
||||
WorkerState::Available => {
|
||||
loop {
|
||||
match Pin::new(&mut self.rx).poll_next(cx) {
|
||||
// handle incoming tcp stream
|
||||
// handle incoming io stream
|
||||
Poll::Ready(Some(WorkerCommand(msg))) => {
|
||||
match self.check_readiness(cx) {
|
||||
Ok(true) => {
|
||||
|
@ -29,6 +29,8 @@ fn test_bind() {
|
||||
let h = thread::spawn(move || {
|
||||
let sys = actix_rt::System::new("test");
|
||||
let srv = Server::build()
|
||||
.workers(1)
|
||||
.disable_signals()
|
||||
.bind("test", addr, move || service_fn(|_| ok::<_, ()>(())))
|
||||
.unwrap()
|
||||
.start();
|
||||
@ -51,14 +53,16 @@ fn test_listen() {
|
||||
let h = thread::spawn(move || {
|
||||
let sys = actix_rt::System::new("test");
|
||||
let lst = net::TcpListener::bind(addr).unwrap();
|
||||
let srv = Server::build()
|
||||
Server::build()
|
||||
.disable_signals()
|
||||
.workers(1)
|
||||
.listen("test", lst, move || service_fn(|_| ok::<_, ()>(())))
|
||||
.unwrap()
|
||||
.start();
|
||||
let _ = tx.send((srv, actix_rt::System::current()));
|
||||
let _ = tx.send(actix_rt::System::current());
|
||||
let _ = sys.run();
|
||||
});
|
||||
let (_, sys) = rx.recv().unwrap();
|
||||
let sys = rx.recv().unwrap();
|
||||
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
assert!(net::TcpStream::connect(addr).is_ok());
|
||||
@ -72,10 +76,12 @@ fn test_start() {
|
||||
let addr = unused_addr();
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
||||
let h = thread::spawn(move || {
|
||||
let _ = thread::spawn(move || {
|
||||
let sys = actix_rt::System::new("test");
|
||||
let srv: Server = Server::build()
|
||||
.backlog(100)
|
||||
.workers(1)
|
||||
.disable_signals()
|
||||
.bind("test", addr, move || {
|
||||
service_fn(|io: TcpStream| {
|
||||
async move {
|
||||
@ -126,7 +132,7 @@ fn test_start() {
|
||||
|
||||
thread::sleep(time::Duration::from_millis(100));
|
||||
let _ = sys.stop();
|
||||
let _ = h.join();
|
||||
// let _ = h.join();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -142,6 +148,7 @@ fn test_configure() {
|
||||
let num = num2.clone();
|
||||
let sys = actix_rt::System::new("test");
|
||||
let srv = Server::build()
|
||||
.disable_signals()
|
||||
.configure(move |cfg| {
|
||||
let num = num.clone();
|
||||
let lst = net::TcpListener::bind(addr3).unwrap();
|
||||
|
@ -1,5 +1,9 @@
|
||||
# Changes
|
||||
|
||||
## [1.0.0-alpha.3] - 2019-12-xx
|
||||
|
||||
* Migrate to `tokio=0.2.2`
|
||||
|
||||
## [1.0.0-alpha.2] - 2019-12-02
|
||||
|
||||
* Re-export `test` attribute macros
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-testing"
|
||||
version = "1.0.0-alpha.2"
|
||||
version = "1.0.0-alpha.3"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix testing utils"
|
||||
keywords = ["network", "framework", "async", "futures"]
|
||||
@ -17,13 +17,11 @@ name = "actix_testing"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
actix-rt = "1.0.0-alpha.2"
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
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"
|
||||
|
||||
log = "0.4"
|
||||
net2 = "0.2"
|
||||
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_server::{Server, ServerBuilder, ServiceFactory};
|
||||
|
||||
use net2::TcpBuilder;
|
||||
use tokio_net::driver::Handle;
|
||||
|
||||
#[cfg(not(test))] // Work around for rust-lang/rust#62127
|
||||
pub use actix_macros::test;
|
||||
@ -25,7 +23,8 @@ pub use actix_macros::test;
|
||||
/// use actix_service::{service_fn};
|
||||
/// use actix_testing::TestServer;
|
||||
///
|
||||
/// fn main() {
|
||||
/// #[actix_rt::main]
|
||||
/// async fn main() {
|
||||
/// let srv = TestServer::with(|| service_fn(
|
||||
/// |sock| async move {
|
||||
/// println!("New connection: {:?}", sock);
|
||||
@ -142,7 +141,7 @@ impl TestServerRuntime {
|
||||
|
||||
/// Connect to server, return tokio 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
|
||||
|
||||
[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
|
||||
|
||||
* Split openssl accetor from actix-server package
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-tls"
|
||||
version = "1.0.0-alpha.1"
|
||||
version = "1.0.0-alpha.3"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix tls services"
|
||||
keywords = ["network", "framework", "async", "futures"]
|
||||
@ -30,9 +30,9 @@ rustls = ["rust-tls", "webpki"]
|
||||
|
||||
[dependencies]
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-codec = "0.2.0-alpha.2"
|
||||
actix-utils = "1.0.0-alpha.2"
|
||||
actix-rt = "1.0.0-alpha.2"
|
||||
actix-codec = "0.2.0-alpha.3"
|
||||
actix-utils = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
derive_more = "0.99.2"
|
||||
either = "1.5.2"
|
||||
futures = "0.3.1"
|
||||
@ -40,15 +40,14 @@ log = "0.4"
|
||||
|
||||
# openssl
|
||||
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
|
||||
rust-tls = { version = "0.16.0", package = "rustls", optional = true }
|
||||
webpki = { version = "0.21", optional = true }
|
||||
webpki-roots = { version = "0.17", optional = true }
|
||||
# tokio-rustls = { version = "0.12.0-alpha.2", optional = true }
|
||||
# tokio-rustls = { git = "https://github.com/quininer/tokio-rustls.git", branch = "tokio-0.2", optional = true }
|
||||
tokio-rustls = { version = "0.12.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
bytes = "0.4"
|
||||
actix-testing = { version="1.0.0-alpha.2" }
|
||||
bytes = "0.5"
|
||||
actix-testing = { version="1.0.0-alpha.3" }
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
## [1.0.0-alpha.3] - 2019-12-xx
|
||||
|
||||
* Migrate to `tokio=0.2.2`
|
||||
|
||||
* Fix oneshot
|
||||
|
||||
## [1.0.0-alpha.2] - 2019-12-02
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-utils"
|
||||
version = "1.0.0-alpha.2"
|
||||
version = "1.0.0-alpha.3"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix utils - various actix net related services"
|
||||
keywords = ["network", "framework", "async", "futures"]
|
||||
@ -19,9 +19,9 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0-alpha.2"
|
||||
actix-codec = "0.2.0-alpha.2"
|
||||
bytes = "0.4"
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-codec = "0.2.0-alpha.3"
|
||||
bytes = "0.5.2"
|
||||
either = "1.5.2"
|
||||
futures = "0.3.1"
|
||||
pin-project = "0.4.6"
|
||||
|
@ -3,9 +3,9 @@ use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
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 futures::future::{ok, Ready};
|
||||
|
||||
@ -81,13 +81,13 @@ where
|
||||
F: Fn() -> E,
|
||||
{
|
||||
pub fn new(ka: Duration, time: LowResTimeService, f: F) -> Self {
|
||||
let expire = time.now() + ka;
|
||||
let expire = Instant::from_std(time.now() + ka);
|
||||
KeepAliveService {
|
||||
f,
|
||||
ka,
|
||||
time,
|
||||
expire,
|
||||
delay: delay(expire),
|
||||
delay: delay_until(expire),
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
@ -105,7 +105,7 @@ where
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
match Pin::new(&mut self.delay).poll(cx) {
|
||||
Poll::Ready(_) => {
|
||||
let now = self.time.now();
|
||||
let now = Instant::from_std(self.time.now());
|
||||
if self.expire <= now {
|
||||
Poll::Ready(Err((self.f)()))
|
||||
} else {
|
||||
@ -119,7 +119,7 @@ where
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,11 @@
|
||||
# Changes
|
||||
|
||||
## [0.2.0] - 2019-12-05
|
||||
|
||||
* Update http to 0.2
|
||||
|
||||
* Update regex to 1.3
|
||||
|
||||
## [0.1.5] - 2019-05-15
|
||||
|
||||
* Remove debug prints
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-router"
|
||||
version = "0.1.5"
|
||||
version = "0.2.0"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Path router"
|
||||
keywords = ["actix"]
|
||||
@ -20,13 +20,12 @@ path = "src/lib.rs"
|
||||
default = ["http"]
|
||||
|
||||
[dependencies]
|
||||
bytes = "0.4"
|
||||
regex = "1.0"
|
||||
regex = "1.3.1"
|
||||
serde = "1.0.80"
|
||||
string = "0.2.0"
|
||||
log = "0.4"
|
||||
http = { version="0.1.14", optional=true }
|
||||
string = "0.2.1"
|
||||
log = "0.4.8"
|
||||
http = { version="0.2.0", optional=true }
|
||||
|
||||
[dev-dependencies]
|
||||
http = "0.1.14"
|
||||
http = "0.2.0"
|
||||
serde_derive = "1.0"
|
||||
|
@ -491,7 +491,8 @@ pub(crate) fn insert_slash(path: &str) -> String {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use http::{HttpTryFrom, Uri};
|
||||
use http::Uri;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
#[test]
|
||||
fn test_parse_static() {
|
||||
|
@ -200,7 +200,8 @@ fn restore_ch(d1: u8, d2: u8) -> Option<u8> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use http::{HttpTryFrom, Uri};
|
||||
use http::Uri;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use super::*;
|
||||
use crate::{Path, ResourceDef};
|
||||
|
Loading…
Reference in New Issue
Block a user