[−][src]Trait kompact::prelude::ComponentDefinition
The core trait every component must implement
Should usually simply be derived using #[derive(ComponentDefinition)]
.
Only implement this manually if you need special execution logic, for example for custom fairness models.
Note
The derive macro additionally provides implementation of ProvideRef or RequireRef for each of the component's ports. It is generally recommended to do so as well, when not using the derive macro, as it enables some rather convenient APIs.
Required methods
fn setup(&mut self, self_component: Arc<Component<Self>>)
Prepare the component for being run
You must call initialise on this component's context instance.
You must call set_parent (or RequiredPort::set_parent) for each of the component's ports.
fn execute(&mut self, max_events: usize, skip: usize) -> ExecuteResult
Execute events on the component's ports
You may run up to max_events
events from the component's ports.
The skip
value normally contains the offset where the last invocation stopped.
However, you can specify the next value when you create the returning ExecuteResult,
so you can custome the semantics of this value, if desired.
fn ctx(&self) -> &ComponentContext<Self>
Return a reference the component's context field
fn ctx_mut(&mut self) -> &mut ComponentContext<Self>
Return a mutable reference the component's context field
fn type_name() -> &'static str
Return the name of the component's type
This is only used for the logging MDC, so you can technically return whatever you like. It simply helps with debugging if it's related to the actual struct name.
Provided methods
fn spawn_local<F>(
&mut self,
f: impl FnOnce(ComponentDefinitionAccess<Self>) -> F
) where
Self: 'static,
F: Future<Output = Handled> + Send + 'static,
&mut self,
f: impl FnOnce(ComponentDefinitionAccess<Self>) -> F
) where
Self: 'static,
F: Future<Output = Handled> + Send + 'static,
Run a Future on this component, allowing it mutable access to the component's internal state on every poll.
Please see the documentation for ComponentDefinitionAccess for details on how the internal state may (and may not) be used.
Example
#[derive(ComponentDefinition, Actor)] struct AsyncComponent { ctx: ComponentContext<Self>, flag: bool, } impl AsyncComponent { fn new() -> Self { AsyncComponent { ctx: ComponentContext::uninitialised(), flag: false, } } } impl ComponentLifecycle for AsyncComponent { fn on_start(&mut self) -> Handled { // on nightly you can just write: async move |mut async_self| {...} self.spawn_local(move |mut async_self| async move { async_self.flag = true; Handled::Ok }); Handled::Ok } }
See Also
In order to suspend processing of all other messages and events while completing a future, use block_on.
In order to run a large future which does not need access to component's internal state at all or until the very end, consider using spawn_off.
fn spawn_off<R: Send + 'static>(
&self,
future: impl Future<Output = R> + 'static + Send
) -> JoinHandle<R>
&self,
future: impl Future<Output = R> + 'static + Send
) -> JoinHandle<R>
Run a Future on this system's executor pool and return a handle to the result
Handles can be awaited like any other future.
Note
The current API is not as efficient as calling FuturesExecutor::spawn
directly, due to some trait object indirection in Kompact systems.
Thus, if performance is important, it is recommended to maintain a (non trait-object) handle
to the actual Executor
pool being used and call its spawn
function instead.
This API is really just a somewhat roundabout convenience for doing the same.