add comment for custom executor example

This commit is contained in:
fakeshadow 2020-10-30 20:50:05 +08:00
parent bb4b0d1a63
commit 81bbf725a6
13 changed files with 53 additions and 47 deletions

View File

@ -12,7 +12,7 @@ use futures_channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
use futures_channel::oneshot::{channel, Canceled, Sender};
use tokio::stream::Stream;
use crate::runtime::{DefaultExec, ExecFactory};
use crate::runtime::{ActixExec, ExecFactory};
use crate::system::System;
thread_local!(
@ -79,7 +79,7 @@ impl Arbiter {
#[deprecated(since = "1.2.0", note = "Please use actix_rt::spawn instead")]
pub fn spawn<F: Future<Output = ()> + 'static>(f: F) {
DefaultExec::spawn(f)
ActixExec::spawn(f)
}
/// Returns the current thread's arbiter's address. If no Arbiter is present, then this
@ -105,7 +105,7 @@ impl Arbiter {
/// Spawn new thread and run event loop in spawned thread.
/// Returns address of newly created arbiter.
pub fn new() -> Arbiter {
Self::new_with::<DefaultExec>()
Self::new_with::<ActixExec>()
}
pub fn new_with<E: ExecFactory>() -> Arbiter {

View File

@ -14,7 +14,7 @@ mod system;
pub use self::arbiter::Arbiter;
pub use self::builder::{Builder, SystemRunner};
pub use self::runtime::{DefaultExec, ExecFactory};
pub use self::runtime::{ActixExec, ExecFactory};
pub use self::system::System;
#[doc(hidden)]
@ -33,7 +33,7 @@ pub fn spawn<F>(f: F)
where
F: Future<Output = ()> + 'static,
{
DefaultExec::spawn(f);
ActixExec::spawn(f);
}
/// Asynchronous signal handling

View File

@ -78,12 +78,10 @@ pub trait ExecFactory: Sized + Send + Sync + Unpin + 'static {
///
/// [mod]: index.html
#[derive(Copy, Clone, Debug)]
pub struct DefaultExec;
pub struct ActixExec;
pub type DefaultExecutor = (runtime::Runtime, LocalSet);
impl ExecFactory for DefaultExec {
type Executor = DefaultExecutor;
impl ExecFactory for ActixExec {
type Executor = (runtime::Runtime, LocalSet);
type Sleep = tokio::time::Delay;
fn build() -> io::Result<Self::Executor> {

View File

@ -7,7 +7,7 @@ use futures_channel::mpsc::UnboundedSender;
use crate::arbiter::{Arbiter, SystemCommand};
use crate::builder::{Builder, SystemRunner};
use crate::runtime::ExecFactory;
use crate::DefaultExec;
use crate::ActixExec;
static SYSTEM_COUNT: AtomicUsize = AtomicUsize::new(0);
@ -29,8 +29,8 @@ impl System {
/// Create new system.
///
/// This method panics if it can not create tokio runtime
pub fn new<T: Into<String>>(name: T) -> SystemRunner<DefaultExec> {
Self::new_with::<DefaultExec, T>(name)
pub fn new<T: Into<String>>(name: T) -> SystemRunner<ActixExec> {
Self::new_with::<ActixExec, T>(name)
}
/// This function will start tokio runtime and will finish once the
@ -40,7 +40,7 @@ impl System {
where
F: FnOnce() + 'static,
{
Self::run_with::<DefaultExec, F>(f)
Self::run_with::<ActixExec, F>(f)
}
/// Get current running system.

View File

@ -25,12 +25,12 @@ actix-rt = "1.1.1"
actix-codec = "0.3.0"
actix-utils = "2.0.0"
futures-channel = { version = "0.3.4", default-features = false }
futures-util = { version = "0.3.4", default-features = false }
log = "0.4"
num_cpus = "1.13"
mio = "0.6.19"
socket2 = "0.3"
futures-channel = { version = "0.3.4", default-features = false }
futures-util = { version = "0.3.4", default-features = false, features = ["sink"] }
slab = "0.4"
# unix domain sockets
@ -38,8 +38,9 @@ slab = "0.4"
mio-uds = { version = "0.6.7" }
[dev-dependencies]
bytes = "0.5"
env_logger = "0.7"
actix-testing = "1.0.0"
async-std = { version = "1.6.5", features = ["unstable", "tokio02"] }
bytes = "0.5"
env_logger = "0.7"
futures-util = { version = "0.3.4", default-features = false, features = ["sink"] }
tokio = { version = "0.2", features = ["io-util"] }

View File

@ -23,6 +23,7 @@ use futures_util::future::ok;
use log::{error, info};
fn main() -> io::Result<()> {
// annotate executor type and block_on it
actix_rt::System::new_with::<AsyncStdExec, _>("actix").block_on(async {
env::set_var("RUST_LOG", "actix=trace,basic=trace");
env_logger::init();
@ -32,14 +33,15 @@ fn main() -> io::Result<()> {
let addr = ("127.0.0.1", 8080);
info!("starting server on port: {}", &addr.0);
// Bind socket address and start worker(s). By default, the server uses the number of available
// logical CPU cores as the worker count. For this reason, the closure passed to bind needs
// to return a service *factory*; so it can be created once per worker.
// annotate again as the server would want to spawn tasks on executor.
Server::build_with::<AsyncStdExec>()
.bind("echo", addr, move || {
let count = Arc::clone(&count);
let num2 = Arc::clone(&count);
// stream type must impl actix_server::FromStream trait for handling the stream.
// at this point stream type can be generic if you want to passing it though
// pipeline but at last a service must give it a concrete type to work with.
pipeline_factory(move |mut stream: AsyncStdTcpStream| {
let count = Arc::clone(&count);
@ -89,19 +91,23 @@ fn main() -> io::Result<()> {
})
}
// custom executor
struct AsyncStdExec;
// stream type can work on the custom executor
struct AsyncStdTcpStream(async_std::net::TcpStream);
// server would pass a StdStream enum and you have to convert it to your stream type.
impl FromStream for AsyncStdTcpStream {
fn from_stdstream(stream: StdStream) -> std::io::Result<Self> {
match stream {
StdStream::Tcp(tcp) => Ok(AsyncStdTcpStream(async_std::net::TcpStream::from(tcp))),
_ => unimplemented!(),
StdStream::Uds(_) => unimplemented!(),
}
}
}
// impl trait for custom executor so server can/block_on spawn tasks
impl ExecFactory for AsyncStdExec {
type Executor = ();
type Sleep = Pin<Box<dyn Future<Output = ()> + Send + 'static>>;

View File

@ -151,7 +151,7 @@ where
.name("actix-server accept loop".to_owned())
.spawn(move || {
System::set_current(sys);
let mut accept = Accept::<Exec>::new(rx, socks, workers, srv);
let mut accept = Self::new(rx, socks, workers, srv);
// Start listening for incoming commands
if let Err(err) = accept.poll.register(
@ -182,7 +182,7 @@ where
socks: Vec<(Token, StdListener)>,
workers: Vec<WorkerClient>,
srv: Server,
) -> Accept<Exec> {
) -> Self {
// Create a poll instance
let poll = match mio::Poll::new() {
Ok(poll) => poll,

View File

@ -1,3 +1,4 @@
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::task::{Context, Poll};
@ -5,12 +6,12 @@ use std::time::Duration;
use std::{io, mem, net};
use actix_rt::net::TcpStream;
use actix_rt::{DefaultExec, ExecFactory, System};
use actix_rt::{ActixExec, ExecFactory, System};
use futures_channel::mpsc::{unbounded, UnboundedReceiver};
use futures_channel::oneshot;
use futures_util::future::ready;
use futures_util::stream::FuturesUnordered;
use futures_util::{future::Future, ready, stream::Stream, FutureExt, StreamExt};
use futures_util::stream::{FuturesUnordered, Stream};
use futures_util::{ready, FutureExt, StreamExt};
use log::{error, info};
use socket2::{Domain, Protocol, Socket, Type};
@ -24,7 +25,7 @@ use crate::worker::{self, Worker, WorkerAvailability, WorkerClient};
use crate::{FromStream, Token};
/// Server builder
pub struct ServerBuilder<Exec = DefaultExec> {
pub struct ServerBuilder<Exec = ActixExec> {
threads: usize,
token: Token,
backlog: i32,
@ -53,7 +54,7 @@ where
{
/// Create new Server builder instance with default tokio executor.
pub fn new() -> Self {
ServerBuilder::<DefaultExec>::new_with()
ServerBuilder::<ActixExec>::new_with()
}
/// Create new Server builder instance with a generic executor.

View File

@ -1,10 +1,13 @@
use std::collections::HashMap;
use std::future::Future;
use std::marker::PhantomData;
use std::{fmt, io, net};
use actix_rt::net::TcpStream;
use actix_rt::ExecFactory;
use actix_service as actix;
use actix_utils::counter::CounterGuard;
use futures_util::future::{ok, Future, FutureExt, LocalBoxFuture};
use futures_util::future::{ok, FutureExt, LocalBoxFuture};
use log::error;
use super::builder::bind_addr;
@ -12,8 +15,6 @@ use super::service::{
BoxedServerService, InternalServiceFactory, ServerMessage, StreamService,
};
use super::Token;
use actix_rt::ExecFactory;
use std::marker::PhantomData;
pub struct ServiceConfig {
pub(crate) services: Vec<(String, net::TcpListener)>,
@ -276,9 +277,9 @@ where
type Request = (Option<CounterGuard>, ServerMessage);
type Response = ();
type Error = ();
type InitError = ();
type Config = ();
type Service = BoxedServerService;
type InitError = ();
type Future = LocalBoxFuture<'static, Result<BoxedServerService, ()>>;
fn new_service(&self, _: ()) -> Self::Future {

View File

@ -1,13 +1,12 @@
use std::future::Future;
use std::io;
use std::marker::PhantomData;
use std::pin::Pin;
use std::task::{Context, Poll};
use futures_util::future::lazy;
use actix_rt::ExecFactory;
use crate::server::Server;
use actix_rt::ExecFactory;
use std::marker::PhantomData;
/// Different types of process signals
#[allow(dead_code)]
@ -37,12 +36,13 @@ where
Exec: ExecFactory,
{
pub(crate) fn start(srv: Server) -> io::Result<()> {
Exec::spawn(lazy(|_| {
Exec::spawn(async {
#[cfg(not(unix))]
{
Exec::spawn(Signals {
srv,
stream: Box::pin(actix_rt::signal::ctrl_c()),
_exec: PhantomData,
});
}
#[cfg(unix)]
@ -75,7 +75,7 @@ where
_exec: PhantomData,
})
}
}));
});
Ok(())
}

View File

@ -1,4 +1,4 @@
use std::marker::PhantomData;
use std::future::Future;
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
@ -10,7 +10,7 @@ use actix_utils::counter::Counter;
use futures_channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
use futures_channel::oneshot;
use futures_util::future::{join_all, LocalBoxFuture, MapOk};
use futures_util::{future::Future, stream::Stream, FutureExt, TryFutureExt};
use futures_util::{stream::Stream, FutureExt, TryFutureExt};
use log::{error, info, trace};
use crate::accept::AcceptNotify;
@ -137,7 +137,6 @@ where
factories: Vec<Box<dyn InternalServiceFactory>>,
state: WorkerState<Exec>,
shutdown_timeout: time::Duration,
_exec: PhantomData<Exec>,
}
struct WorkerService {
@ -189,7 +188,6 @@ where
services: Vec::new(),
conns: conns.clone(),
state: WorkerState::Unavailable(Vec::new()),
_exec: PhantomData,
});
let mut fut: Vec<MapOk<LocalBoxFuture<'static, _>, _>> = Vec::new();

View File

@ -2,7 +2,7 @@ use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
use std::sync::{mpsc, Arc};
use std::{net, thread, time};
use actix_rt::DefaultExec;
use actix_rt::ActixExec;
use actix_server::Server;
use actix_service::fn_service;
use futures_util::future::{lazy, ok};
@ -169,11 +169,11 @@ fn test_configure() {
.listen("addr3", lst)
.apply(move |rt| {
let num = num.clone();
rt.service::<_, _, DefaultExec>(
rt.service::<_, _, ActixExec>(
"addr1",
fn_service(|_| ok::<_, ()>(())),
);
rt.service::<_, _, DefaultExec>(
rt.service::<_, _, ActixExec>(
"addr3",
fn_service(|_| ok::<_, ()>(())),
);

View File

@ -25,9 +25,10 @@ use std::{
},
};
use actix_rt::net::TcpStream;
use actix_server::Server;
use actix_service::pipeline_factory;
use actix_tls::rustls::Acceptor as RustlsAcceptor;
use actix_tls::rustls::{Acceptor as RustlsAcceptor, Acceptor};
use futures_util::future::ok;
use log::info;
use rust_tls::{
@ -56,7 +57,7 @@ async fn main() -> io::Result<()> {
.set_single_cert(cert_chain, keys.remove(0))
.unwrap();
let tls_acceptor = RustlsAcceptor::new(tls_config);
let tls_acceptor = RustlsAcceptor::<TcpStream>::new(tls_config);
let count = Arc::new(AtomicUsize::new(0));