1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-30 21:04:35 +01:00

add Arbiter::exec_fn and exec functions

This commit is contained in:
Nikolay Kim 2019-03-11 22:51:17 -07:00
parent 8e13ba7bce
commit f1d4bcef4b
4 changed files with 67 additions and 9 deletions

View File

@ -1,5 +1,14 @@
# Changes # Changes
## [0.2.1] - 2019-03-11
### Added
* Arbiter::exec_fn - execute fn on the arbiter's thread
* Arbiter::exec - execute fn on the arbiter's thread and wait result
## [0.2.0] - 2019-03-06 ## [0.2.0] - 2019-03-06
* `run` method returns `io::Result<()>` * `run` method returns `io::Result<()>`

View File

@ -1,6 +1,6 @@
[package] [package]
name = "actix-rt" name = "actix-rt"
version = "0.2.0" version = "0.2.1"
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"]

View File

@ -4,7 +4,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use std::{fmt, thread}; use std::{fmt, thread};
use futures::sync::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}; use futures::sync::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
use futures::sync::oneshot::{channel, Sender}; use futures::sync::oneshot::{channel, Canceled, Sender};
use futures::{future, Async, Future, IntoFuture, Poll, Stream}; use futures::{future, Async, Future, IntoFuture, Poll, Stream};
use tokio_current_thread::spawn; use tokio_current_thread::spawn;
@ -22,6 +22,7 @@ pub(crate) static COUNT: AtomicUsize = AtomicUsize::new(0);
pub(crate) enum ArbiterCommand { pub(crate) enum ArbiterCommand {
Stop, Stop,
Execute(Box<Future<Item = (), Error = ()> + Send>), Execute(Box<Future<Item = (), Error = ()> + Send>),
ExecuteFn(Box<FnExec>),
} }
impl fmt::Debug for ArbiterCommand { impl fmt::Debug for ArbiterCommand {
@ -29,6 +30,7 @@ impl fmt::Debug for ArbiterCommand {
match self { match self {
ArbiterCommand::Stop => write!(f, "ArbiterCommand::Stop"), ArbiterCommand::Stop => write!(f, "ArbiterCommand::Stop"),
ArbiterCommand::Execute(_) => write!(f, "ArbiterCommand::Execute"), ArbiterCommand::Execute(_) => write!(f, "ArbiterCommand::Execute"),
ArbiterCommand::ExecuteFn(_) => write!(f, "ArbiterCommand::ExecuteFn"),
} }
} }
} }
@ -158,6 +160,35 @@ impl Arbiter {
.0 .0
.unbounded_send(ArbiterCommand::Execute(Box::new(future))); .unbounded_send(ArbiterCommand::Execute(Box::new(future)));
} }
/// Send a function to the arbiter's thread and exeute.
pub fn exec_fn<F>(&self, f: F)
where
F: FnOnce() + Send + 'static,
{
let _ = self
.0
.unbounded_send(ArbiterCommand::ExecuteFn(Box::new(move || {
let _ = f();
})));
}
/// Send a function to the arbiter's thread, exeute and return result.
pub fn exec<F, R>(&self, f: F) -> impl Future<Item = R, Error = Canceled>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
let (tx, rx) = channel();
let _ = self
.0
.unbounded_send(ArbiterCommand::ExecuteFn(Box::new(move || {
if !tx.is_canceled() {
let _ = tx.send(f());
}
})));
rx
}
} }
struct ArbiterController { struct ArbiterController {
@ -194,6 +225,9 @@ impl Future for ArbiterController {
ArbiterCommand::Execute(fut) => { ArbiterCommand::Execute(fut) => {
spawn(fut); spawn(fut);
} }
ArbiterCommand::ExecuteFn(f) => {
f.call_box();
}
}, },
Ok(Async::NotReady) => return Ok(Async::NotReady), Ok(Async::NotReady) => return Ok(Async::NotReady),
} }
@ -257,11 +291,16 @@ impl Future for SystemArbiter {
} }
} }
// /// Execute function in arbiter's thread pub trait FnExec: Send + 'static {
// impl<I: Send, E: Send> Handler<Execute<I, E>> for SystemArbiter { fn call_box(self: Box<Self>);
// type Result = Result<I, E>; }
// fn handle(&mut self, msg: Execute<I, E>, _: &mut Context<Self>) -> Result<I, E> { impl<F> FnExec for F
// msg.exec() where
// } F: FnOnce() + Send + 'static,
// } {
#[cfg_attr(feature = "cargo-clippy", allow(boxed_local))]
fn call_box(self: Box<Self>) {
(*self)()
}
}

View File

@ -1,14 +1,18 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::io; use std::io;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use futures::sync::mpsc::UnboundedSender; use futures::sync::mpsc::UnboundedSender;
use crate::arbiter::{Arbiter, SystemCommand}; use crate::arbiter::{Arbiter, SystemCommand};
use crate::builder::{Builder, SystemRunner}; use crate::builder::{Builder, SystemRunner};
static SYSTEM_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
/// System is a runtime manager. /// System is a runtime manager.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct System { pub struct System {
id: usize,
sys: UnboundedSender<SystemCommand>, sys: UnboundedSender<SystemCommand>,
arbiter: Arbiter, arbiter: Arbiter,
stop_on_panic: bool, stop_on_panic: bool,
@ -29,6 +33,7 @@ impl System {
sys, sys,
arbiter, arbiter,
stop_on_panic, stop_on_panic,
id: SYSTEM_COUNT.fetch_add(1, Ordering::SeqCst),
}; };
System::set_current(sys.clone()); System::set_current(sys.clone());
sys sys
@ -82,6 +87,11 @@ impl System {
}) })
} }
/// System id
pub fn id(&self) -> usize {
self.id
}
/// Stop the system /// Stop the system
pub fn stop(&self) { pub fn stop(&self) {
self.stop_with_code(0) self.stop_with_code(0)