Skip to main content

ComponentDefinition

Trait ComponentDefinition 

Source
pub trait ComponentDefinition:
    DynamicComponentDefinition
    + Sized
    + 'static {
    // Required methods
    fn setup(&mut self, self_component: Arc<Component<Self>>);
    fn execute(&mut self, max_events: usize, skip: usize) -> ExecuteResult;
    fn ctx(&self) -> &ComponentContext<Self>;
    fn ctx_mut(&mut self) -> &mut ComponentContext<Self>;
    fn type_name() -> &'static str;

    // Provided methods
    fn spawn_local<F>(
        &mut self,
        f: impl FnOnce(ComponentDefinitionAccess<Self>) -> F,
    )
       where Self: 'static,
             F: Future<Output = Result<Handled, HandlerError>> + Send + 'static { ... }
    fn spawn_off<R>(
        &self,
        future: impl Future<Output = R> + Send + 'static,
    ) -> Receiver<R>
       where R: Send + 'static { ... }
}
Expand description

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§

Source

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.

Source

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.

Source

fn ctx(&self) -> &ComponentContext<Self>

Return a reference the component’s context field

Source

fn ctx_mut(&mut self) -> &mut ComponentContext<Self>

Return a mutable reference the component’s context field

Source

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§

Source

fn spawn_local<F>( &mut self, f: impl FnOnce(ComponentDefinitionAccess<Self>) -> F, )
where Self: 'static, F: Future<Output = Result<Handled, HandlerError>> + 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) -> HandlerResult {
        // 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.

Source

fn spawn_off<R>( &self, future: impl Future<Output = R> + Send + 'static, ) -> Receiver<R>
where R: Send + 'static,

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.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§