Skip to content

Commit

Permalink
cleanup: improve agent docs, handle world.run() fallback behavior if …
Browse files Browse the repository at this point in the history
…no agents were added
  • Loading branch information
kinrezC committed Feb 2, 2024
1 parent 70db06d commit 55425dc
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 45 deletions.
23 changes: 2 additions & 21 deletions arbiter-engine/src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,8 @@ use thiserror::Error;
/// dependency.
///
/// # How it works
/// The [`Agent`] works by implementing the [`StateMachine`] trait. When the
/// [`World`] that owns the [`Agent`] is asked to enter into a new state, the
/// [`World`] will ask each [`Agent`] it owns to run that state transition by
/// calling [`StateMachine::run_state`]. All of the [`Agent`]s at once will then
/// will be able to be asked to block and wait to finish their state transition
/// by calling [`StateMachine::transition`]. Ultimately, the [`Agent`] will
/// transition through the following states:
/// 1. [`State::Uninitialized`]: The [`Agent`] has been created, but has not
/// been started.
/// 2. [`State::Syncing`]: The [`Agent`] is syncing with the world. This is
/// where the [`Agent`] can be brought up to date with the latest state of the
/// world. This could be used if the world was stopped and later restarted.
/// 3. [`State::Startup`]: The [`Agent`] is starting up. This is where the
/// [`Agent`] can be initialized and setup.
/// 4. [`State::Processing`]: The [`Agent`] is processing. This is where the
/// [`Agent`] can process events and produce actions. The [`State::Processing`]
/// stage may run for a long time before all [`Agent`]s are finished processing.
/// This is the main stage of the [`Agent`] that predominantly runs automation.
/// 5. [`State::Stopped`]: The [`Agent`] is stopped. This is where the [`Agent`]
/// can be stopped and state of the [`World`] and its [`Agent`]s can be
/// offloaded and saved.
/// When the [`World`] that owns the [`Agent`] is ran, it has each [`Agent`] run each of its [`Behavior`]s `startup()` methods.
/// The [`Behavior`]s themselves will return a stream of events that then let the [`Behavior`] move into the `State::Processing` stage.
pub struct Agent {
/// Identifier for this agent.
/// Used for routing messages.
Expand Down
1 change: 1 addition & 0 deletions arbiter-engine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use std::collections::HashMap;

use anyhow::{anyhow, Result};
use serde::{Deserialize, Serialize};
#[allow(unused)]
use tracing::{debug, trace, warn};
Expand Down
33 changes: 9 additions & 24 deletions arbiter-engine/src/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,9 @@ use crate::{agent::Agent, machine::State, messager::Messager};
/// responsible for managing the agents and their state transitions.
///
/// # How it works
/// The [`World`] works by implementing the [`StateMachine`] trait. When the
/// [`World`] is asked to enter into a new state, it will ask each [`Agent`] it
/// owns to run that state transition by calling [`StateMachine::run_state`].
/// All of the [`Agent`]s at once will then be able to be asked to block and
/// wait to finish their state transition by calling
/// [`StateMachine::transition`]. Ultimately, the [`World`] will transition
/// through the following states:
/// 1. [`State::Uninitialized`]: The [`World`] has been created, but has not
/// been started.
/// 2. [`State::Syncing`]: The [`World`] is syncing with the agents. This is
/// where the [`World`] can be brought up to date with the latest state of the
/// agents. This could be used if the world was stopped and later restarted.
/// 3. [`State::Startup`]: The [`World`] is starting up. This is where the
/// [`World`] can be initialized and setup.
/// 4. [`State::Processing`]: The [`World`] is processing. This is where the
/// [`World`] can process events and produce actions. The [`State::Processing`]
/// stage may run for a long time before all [`World`]s are finished processing.
/// This is the main stage of the [`World`] that predominantly runs automation.
/// 5. [`State::Stopped`]: The [`World`] is stopped. This is where the [`World`]
/// can be stopped and state of the [`World`] and its [`Agent`]s can be
/// offloaded and saved.
/// The [`World`] holds on to a collection of [`Agent`]s and can run them all concurrently when the
/// [`run`] method is called. The [`World`] takes in [`AgentBuilder`]s and when it does so, it creates [`Agent`]s that are now
/// connected to the world via a client ([`Arc<RevmMiddleware>`]) and a messager ([`Messager`]).
pub struct World {
/// The identifier of the world.
pub id: String,
Expand Down Expand Up @@ -91,10 +73,12 @@ impl World {
}

/// Runs the world through up to the [`State::Processing`] stage.
pub async fn run(&mut self) {
pub async fn run(&mut self) -> Result<()> {
let mut tasks = vec![];
// TODO: This unwrap should be checked.
let agents = self.agents.take().unwrap();
let agents = self
.agents
.take()
.ok_or_else(|| anyhow!("No agents found! Has the world already been run?"))?;
let mut messagers = VecDeque::new();
for (_, agent) in agents.iter() {
for _ in &agent.behavior_engines {
Expand All @@ -113,6 +97,7 @@ impl World {
}
}
join_all(tasks).await;
Ok(())
}
}

Expand Down

0 comments on commit 55425dc

Please sign in to comment.