Struct async_executors::exec::TokioTp
source · pub struct TokioTp { /* private fields */ }
tokio_tp
only.Expand description
An executor that uses tokio::runtime::Runtime
.
Example
The following example shows how to pass an executor to a library function.
use
{
futures :: { task::{ Spawn, SpawnExt } } ,
async_executors :: { TokioTp } ,
tokio::runtime :: { Builder } ,
std::convert :: { TryFrom } ,
futures::channel :: { oneshot, oneshot::Sender } ,
};
fn lib_function( exec: impl Spawn, tx: Sender<&'static str> )
{
exec.spawn( async
{
tx.send( "I can spawn from a library" ).expect( "send string" );
}).expect( "spawn task" );
}
fn main()
{
// This creates the runtime with defaults. It enables io and timers based on
// the features enabled on _async_executors_. You can also create `TokioTp` from
// a tokio `Runtime` or a `Handle`.
//
let exec = TokioTp::new().expect( "create tokio threadpool" );
let program = async
{
let (tx, rx) = oneshot::channel();
lib_function( &exec, tx );
assert_eq!( "I can spawn from a library", rx.await.expect( "receive on channel" ) );
};
exec.block_on( program );
}
Unwind Safety.
You must only spawn futures to this API that are unwind safe. Tokio will wrap it in
std::panic::AssertUnwindSafe
and wrap the poll invocation with std::panic::catch_unwind
.
They reason that this is fine because they require Send + 'static
on the future. As far
as I can tell this is wrong. Unwind safety can be circumvented in several ways even with
Send + 'static
(eg. parking_lot::Mutex
is Send + 'static
but !UnwindSafe
).
You should make sure that if your future panics, no code that lives on after the spawned task has unwound, nor any destructors called during the unwind can observe data in an inconsistent state.
If a future is run with block_on
as opposed to spawn
, the panic will not be caught and the
thread calling block_on
will be unwound.
Note that unwind safety is related to logic errors, not related to the memory safety issues that cannot happen
in safe rust (memory safety, undefined behavior, unsoundness, data races, …). See the relevant
catch_unwind RFC
and it’s discussion threads for more info as well as the documentation of std::panic::UnwindSafe
.
Implementations§
source§impl TokioTp
impl TokioTp
sourcepub fn new() -> Result<Self, TokioTpErr>
pub fn new() -> Result<Self, TokioTpErr>
sourcepub fn try_current() -> Result<Self, TokioTpErr>
pub fn try_current() -> Result<Self, TokioTpErr>
Try to construct a TokioTp
from the currently entered Runtime
. You can do this
if you want to construct your runtime with the tokio macros eg:
#[tokio::main]
async fn main()
{
// ...
}
Warning
TokioTp::new()
is preferred over this. It’s brief, doesn’t require macros and is
the intended behavior for this type. The whole library aims at a paradigm without
global executors.
The main footgun here is that you are now already in async context, so you must not
call TokioTp::block_on
. block_on
will panic when run from within an existing
async context.
Errors
Will fail if trying to construct from a current thread runtime or if no runtime is running.
sourcepub fn block_on<F: Future>(&self, f: F) -> F::Output
pub fn block_on<F: Future>(&self, f: F) -> F::Output
Forwards to Runtime::block_on
or Handle::block_on
.
Panics
If called when a runtime is already entered (eg. in async context), like when you created this
executor with TokioTp::try_current
, this will panic.
sourcepub fn shutdown_timeout(self, duration: Duration) -> Result<(), TokioTpErr>
pub fn shutdown_timeout(self, duration: Duration) -> Result<(), TokioTpErr>
See: tokio::runtime::Runtime::shutdown_timeout
This tries to unwrap the Arc<Runtime>
we hold, so that works only if no other clones are around. If this is not the
only reference, self will be returned to you as an error. It means you cannot shutdown the runtime because there are
other clones of the executor still alive.
Errors
TokioTpErr::Cloned
: if the theTokioTp
has been cloned. You can only shut down the last one.TokioTpErr::Handle
: if the theTokioTp
has been created from a handle. That is we don’t own theRuntime
.
sourcepub fn shutdown_background(self) -> Result<(), TokioTpErr>
pub fn shutdown_background(self) -> Result<(), TokioTpErr>
See: tokio::runtime::Runtime::shutdown_background
This tries to unwrap the Arc<Runtime>
we hold, so that works only if no other clones are around. If this is not the
only reference, self will be returned to you as an error. It means you cannot shutdown the runtime because there are
other clones of the executor still alive.
Errors
TokioTpErr::Cloned
: if the theTokioTp
has been cloned. You can only shut down the last one.TokioTpErr::Handle
: if the theTokioTp
has been created from a handle. That is we don’t own theRuntime
.
Trait Implementations§
source§impl<R: Send + 'static> SpawnBlocking<R> for TokioTp
impl<R: Send + 'static> SpawnBlocking<R> for TokioTp
source§fn spawn_blocking<F>(&self, f: F) -> BlockingHandle<R> ⓘwhere
F: FnOnce() -> R + Send + 'static,
fn spawn_blocking<F>(&self, f: F) -> BlockingHandle<R> ⓘwhere F: FnOnce() -> R + Send + 'static,
source§fn spawn_blocking_dyn(
&self,
f: Box<dyn FnOnce() -> R + Send>
) -> BlockingHandle<R> ⓘ
fn spawn_blocking_dyn( &self, f: Box<dyn FnOnce() -> R + Send> ) -> BlockingHandle<R> ⓘ
source§impl<Out: 'static + Send> SpawnHandle<Out> for TokioTp
impl<Out: 'static + Send> SpawnHandle<Out> for TokioTp
source§fn spawn_handle_obj(
&self,
future: FutureObj<'static, Out>
) -> Result<JoinHandle<Out>, SpawnError>
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
JoinHandle
that can be awaited for the output of the future.source§impl TryFrom<Handle> for TokioTp
impl TryFrom<Handle> for TokioTp
source§impl TryFrom<Runtime> for TokioTp
impl TryFrom<Runtime> for TokioTp
source§impl YieldNow for TokioTp
impl YieldNow for TokioTp
source§fn yield_now(&self) -> YieldNowFut ⓘ
fn yield_now(&self) -> YieldNowFut ⓘ
impl TokioIo for TokioTp
tokio_io
only.Auto Trait Implementations§
impl !RefUnwindSafe for TokioTp
impl Send for TokioTp
impl Sync for TokioTp
impl Unpin for TokioTp
impl !UnwindSafe for TokioTp
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<Sp> SpawnExt for Spwhere
Sp: Spawn + ?Sized,
impl<Sp> SpawnExt for Spwhere Sp: Spawn + ?Sized,
source§fn spawn<Fut>(&self, future: Fut) -> Result<(), SpawnError>where
Fut: Future<Output = ()> + Send + 'static,
fn spawn<Fut>(&self, future: Fut) -> Result<(), SpawnError>where Fut: Future<Output = ()> + Send + 'static,
()
to
completion. Read more