Actions
Actions are the leaves of the tree. They require some implementation to be executed.
Action types
There are three types of actions available at that moment:
-
Sync actions: the actions that block the flow until the action get done.
-
Async action: initiate the calculation at the different thread and return
running
immediately. -
Remote action: send the blocking request (http) to the remote host.
-
For heavy actions, preferably to use
async actions
.
Traits
Impl
for sync actions
#![allow(unused)] fn main() { pub trait Impl { fn tick(&self, args: RtArgs, ctx: TreeContextRef) -> Tick; } }
ImplAsync
for async actions
#![allow(unused)] fn main() { pub trait ImplAsync: Sync + Send { fn tick(&self, args: RtArgs, ctx: TreeContextRef) -> Tick; } }
Where args
are the given arguments from the tree definition and invocation and ctx
is a reference of the invocation context with bb
and tracer
Mutability
The actions are intentionally stateless thus they can't mutate. Therefore, it is better off to use blackboard to keep some data between the calls.
How to register action
#![allow(unused)] fn main() { fn simple_delay() { let mut forester_builder = fb("decorators/simple_delay"); forester_builder.register_sync_action("store", StoreData); } }
Async actions
The async actions are executed in the multithreading environment and return the running
tick result instantly.
It does not block the execution of the tree and can be used in parallel nodes, etc.
On the other hand, every time when the tree is reloaded, the tick number is increased that can exceed the limit on ticks if the system has it. Therefore, it needs to take into account (when forester runs with the limit of ticks.)
Remote actions
The remote actions are the actions that send the request to the remote host and wait for the response. For now, it is only http requests with json body and json response.
The remote actions can have access to the blackboard and the tracer if the http-server is running (see http-server).
The remote actions should implement ImplRemote
trait:
#![allow(unused)] fn main() { pub trait ImplRemote: Sync + Send { fn tick(&self, args: RtArgs, ctx: TreeRemoteContextRef) -> Tick; } }
Where args
are the given arguments from the tree definition and invocation and ctx
has the information about the http_server:
#![allow(unused)] fn main() { pub struct TreeRemoteContextRef<'a> { pub curr_ts: Timestamp, // current timestamp pub port: u16, // port of the http server, to access the blackboard and tracer pub env: &'a mut RtEnv, // runtime env to execute the http request } }
The default implementation of the tick
method is available in forester_rs::runtime::action::builtin::remote::RemoteHttpAction
:
#![allow(unused)] fn main() { pub struct RemoteHttpAction { url: String, serv_ip: Option<String>, } }
it accepts the url and the ip of the http server (if it is not localhost, which is a default parameter).
The message is the following:
#![allow(unused)] fn main() { pub struct RemoteActionRequest { pub tick: usize, // current tick pub args: Vec<RtArgument>, // arguments from the tree pub serv_url: String, // url of the http server to get access to the blackboard and tracer } }
The response is the following a TickResult
.
How to implement the client side, please see remote action lib.
Default actions
By default, there are several implementations for http and interactions with bb are available in
#![allow(unused)] fn main() { use forester_rs::runtime::action::builtin::*; }