Struct Handle

Source
pub struct Handle<T>(/* private fields */);
Expand description

A Handle allows for interaction with a previously spawned Agent inside of a tokio runtime context.

If you wish to interact with the Agent outside of a tokio runtime context, use Handle::blocking, which will turn this handle into a BlockingHandle.

The Agent will be automatically stopped once all Handle and BlockingHandle that refer to the agent are dropped, or if the stop method is called.

See the function implementations on this struct for more information on what you can do with an Agent.

Implementations§

Source§

impl<T> Handle<T>

Source

pub fn blocking(self) -> BlockingHandle<T>

Converts this Handle into a BlockingHandle which allows you to interact with the the Agent outside of a tokio runtime context.

Source

pub async fn call<F, R>(&self, func: F) -> Result<R>
where F: FnOnce(&mut T) -> Agent<R> + Send + 'static, R: Send + 'static,

Makes a synchronous call to the agent, waiting for the agent to evaluate the provided function.

The function func is sent to the agent, which then invokes the function, passing a mutable reference to the agent’s state. The return value of func is then sent back to the current task.

If the agent is stopped before evaluating your function, an error will be returned.

Unless you need to dynamically decide whether the agent should stop or continue, get, get_and_update, update, replace, take and stop can be used instead to avoid a bit of boilerplate in specifying whether the agent should stop or continue.

use tokio_agent::{Agent, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let agent = Agent::spawn_task(|| 0);

    let result = agent.call(|x| {
        *x += 1;
        Agent::Continue(*x)
    }).await?;

    assert_eq!(result, 1);
    Ok(())
}
Source

pub async fn clone_state(&self) -> Result<T>
where T: Send + Clone + 'static,

Makes a synchronous call to the agent, asking it to clone its state and send it back to you.

If the agent is stopped before the state is able to be cloned, an error will be returned.

use tokio_agent::{Agent, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let agent = Agent::spawn_task(|| 42);
    let result = agent.clone_state().await?;
    assert_eq!(result, 42);
    Ok(())
}
Source

pub async fn get<F, R>(&self, func: F) -> Result<R>
where F: FnOnce(&T) -> R + Send + 'static, R: Send + 'static,

Makes a synchronous call to the agent, invoking the provided function with an immutable reference to the Agent’s state, and returning the value returned from the function to you.

If the agent is stopped before the state is able to be cloned, an error will be returned.

use tokio_agent::{Agent, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let agent = Agent::spawn_task(|| 42);
    let result = agent.get(|x| *x).await?;
    assert_eq!(result, 42);
    Ok(())
}
Source

pub async fn get_and_update<F, R>(&self, func: F) -> Result<R>
where F: FnOnce(&mut T) -> R + Send + 'static, R: Send + 'static,

Makes a synchronous call to the agent, invoking the provided function with a mutable reference to the Agent’s state, and returning the value returned from the function to you.

If the agent is stopped before the provided function is able to be evaluated, an error will be returned.

use tokio_agent::{Agent, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let agent = Agent::spawn_task(|| 42);
    let result = agent.get_and_update(|x| {
        *x += 1;
        *x
    }).await?;
    assert_eq!(result, 43);

    Ok(())
}
Source

pub async fn update<F>(&self, func: F) -> Result<()>
where F: FnOnce(&mut T) + Send + 'static,

Makes a synchronous call to the agent, invoking the provided function with a mutable reference to the Agent’s state.

If the agent is stopped before the function is able to be evaluated, an error will be returned.

use tokio_agent::{Agent, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let agent = Agent::spawn_task(|| 42);
    agent.update(|x| { *x += 1; }).await?;
    let result = agent.get(|x| *x).await?;
    assert_eq!(result, 43);
    Ok(())
}
Source

pub async fn replace(&self, new_state: T) -> Result<T>
where T: Send + 'static,

Makes a synchronous call to the agent, asking the agent to replace its state with new_state, returning the old state of the agent.

If the agent is stopped before the state is able to be replaced, an error will be returned.

use tokio_agent::{Agent, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let agent = Agent::spawn_task(|| 42);
    let result = agent.replace(43).await?;
    assert_eq!(result, 42);
    let result = agent.get(|x| *x).await?;
    assert_eq!(result, 43);
    Ok(())
}
Source

pub async fn take(&self) -> Result<T>
where T: Default + Send + 'static,

Makes a synchronous call to the agent, asking the agent to replace its state with a new state, constructed using Default::default. The old state is returned back to you.

If the agent is stopped before the state is able to be taken, an error will be returned.

use tokio_agent::{Agent, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let agent = Agent::spawn_task(|| 42);
    let result = agent.take().await?;
    assert_eq!(result, 42);
    let result = agent.get(|x| *x).await?;
    assert_eq!(result, 0);

    Ok(())
}
Source

pub async fn stop(self) -> Result<()>

Makes a synchronous call to the agent, asking the agent to stop.

Returns when the agent has successfully stopped.

If the agent was stopped prior to this function was invoked, an error will be returned.

use tokio_agent::{Agent, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let agent = Agent::spawn_task(|| 42);
    let agent_2 = agent.clone();

    agent.stop().await?;

    assert!(agent_2.stop().await.is_err());

    Ok(())
}
Source

pub async fn monitor(&self)

Monitors the Agent refered to by this handle, returning when the agent dies.

This function is cancel-safe.

use tokio_agent::Agent;

#[tokio::main]
async fn main() {
    let agent = Agent::spawn_task(|| 42);
    let agent_2 = agent.clone();

    tokio::task::spawn(async move {
        agent_2.stop().await.unwrap();
    });

    agent.monitor().await
}

Methods from Deref<Target = HandleCommon<T>>§

Source

pub fn is_stopped(&self) -> bool

Checks if the agent has been stopped.

use tokio_agent::{Agent, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let agent = Agent::spawn_thread(|| 1).unwrap();
    let agent_2 = agent.clone();

    agent.stop().await?;

    assert!(agent_2.is_stopped());

    Ok(())
}
Source

pub fn cast<F>(&self, func: F) -> bool
where F: FnOnce(&mut T) -> Agent<()> + Send + 'static,

Performs a cast (fire and forget) operation on the agent state.

The function func is sent to the agent, which then invokes the function, passing a mutable reference to the agent’s state.

This function will return true if the agent was not stopped at the time of invoking cast, however, a true result does not guarantee that your function will actually exit, as the agent may be stopped prior to evaluating your function.

use tokio_agent::Agent;

let agent = Agent::spawn_thread(|| 42).unwrap().blocking();

agent.cast(|x| {
    *x += 1;
    Agent::Continue(())
});
assert_eq!(agent.get(|x| *x).unwrap(), 43);
Source

pub fn is_same_agent(&self, other: &HandleCommon<T>) -> bool

Returns true if the Agent refered to by this handle is the same as other’s Agent.

use tokio_agent::Agent;

let agent = Agent::spawn_thread(|| "the agent").unwrap();
let agent_2 = agent.clone();

assert!(agent_2.is_same_agent(&agent));

// Additionally, a BlockingHandle can be compared with an Handle as well.

let agent_2 = agent_2.blocking();
assert!(agent_2.is_same_agent(&agent));
assert!(agent.is_same_agent(&agent_2));

let imposter = Agent::spawn_thread(|| "sus").unwrap();
assert!(!agent.is_same_agent(&imposter));

Trait Implementations§

Source§

impl<T> Clone for Handle<T>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T> Debug for Handle<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Deref for Handle<T>

Source§

type Target = HandleCommon<T>

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.

Auto Trait Implementations§

§

impl<T> Freeze for Handle<T>

§

impl<T> RefUnwindSafe for Handle<T>

§

impl<T> Send for Handle<T>

§

impl<T> Sync for Handle<T>

§

impl<T> Unpin for Handle<T>

§

impl<T> UnwindSafe for Handle<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.