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>
impl<T> Handle<T>
Sourcepub fn blocking(self) -> BlockingHandle<T>
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.
Sourcepub async fn call<F, R>(&self, func: F) -> Result<R>
pub async fn call<F, R>(&self, func: F) -> Result<R>
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(())
}
Sourcepub async fn clone_state(&self) -> Result<T>
pub async fn clone_state(&self) -> Result<T>
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(())
}
Sourcepub async fn get<F, R>(&self, func: F) -> Result<R>
pub async fn get<F, R>(&self, func: F) -> Result<R>
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(())
}
Sourcepub async fn get_and_update<F, R>(&self, func: F) -> Result<R>
pub async fn get_and_update<F, R>(&self, func: F) -> Result<R>
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(())
}
Sourcepub async fn update<F>(&self, func: F) -> Result<()>
pub async fn update<F>(&self, func: F) -> Result<()>
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(())
}
Sourcepub async fn replace(&self, new_state: T) -> Result<T>where
T: Send + 'static,
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(())
}
Sourcepub async fn take(&self) -> Result<T>
pub async fn take(&self) -> Result<T>
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(())
}
Sourcepub async fn stop(self) -> Result<()>
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(())
}
Sourcepub async fn monitor(&self)
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>>§
Sourcepub fn is_stopped(&self) -> bool
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(())
}
Sourcepub fn cast<F>(&self, func: F) -> bool
pub fn cast<F>(&self, func: F) -> bool
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);
Sourcepub fn is_same_agent(&self, other: &HandleCommon<T>) -> bool
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));