Skip to main content

SystemHandle

Trait SystemHandle 

Source
pub trait SystemHandle: CanCancelTimers {
Show 13 methods // Required methods fn now(&self) -> Instant; fn create<C, F>(&self, f: F) -> Arc<Component<C>> where F: FnOnce() -> C, C: ComponentDefinition + 'static; fn start(&self, c: &Arc<impl AbstractComponent + ?Sized>); fn start_notify( &self, c: &Arc<impl AbstractComponent + ?Sized>, ) -> KFuture<()> ; fn stop(&self, c: &Arc<impl AbstractComponent + ?Sized>); fn stop_notify( &self, c: &Arc<impl AbstractComponent + ?Sized>, ) -> KFuture<()> ; fn kill(&self, c: Arc<impl AbstractComponent + ?Sized>); fn kill_notify( &self, c: Arc<impl AbstractComponent + ?Sized>, ) -> KFuture<()> ; fn throughput(&self) -> usize; fn max_messages(&self) -> usize; fn shutdown_async(&self); fn deadletter_ref(&self) -> ActorRef<!>; fn spawn<R>( &self, future: impl Future<Output = R> + Send + 'static, ) -> Receiver<R> where R: Send + 'static;
}
Expand description

A limited version of a KompactSystem

This is meant for use from within components, where blocking APIs are unacceptable.

Required Methods§

Source

fn now(&self) -> Instant

Returns the current time according to the system timer.

Source

fn create<C, F>(&self, f: F) -> Arc<Component<C>>
where F: FnOnce() -> C, C: ComponentDefinition + 'static,

Create a new component

Uses f to create an instance of a ComponentDefinition, which is the initialised to form a Component. Since components are shared between threads, the created component is wrapped into an Arc.

Newly created components are not started automatically. Use start or start_notify to start a newly created component, once it is connected properly.

If you need address this component via the network, see the register function.

§Example
let c = system.create(TestComponent1::new);
Source

fn start(&self, c: &Arc<impl AbstractComponent + ?Sized>)

Start a component

A component only handles events/messages once it is started. In particular, a component that isn’t started shouldn’t be scheduled and thus access to its definition should always succeed, for example via on_definition.

§Example
let c = system.create(TestComponent1::new);
system.start(&c);
Source

fn start_notify(&self, c: &Arc<impl AbstractComponent + ?Sized>) -> KFuture<()>

Start a component and complete a future once it has started

When the returned future completes, the component is guaranteed to have started. However, it is not guaranteed to be in an active state, as it could already have been stopped or could have failed since.

A component only handles events/messages once it is started. In particular, a component that isn’t started shouldn’t be scheduled and thus access to its definition should always succeed, for example via on_definition.

§Example
use std::time::Duration;
let c = system.create(TestComponent1::new);
system.start_notify(&c)
      .wait_timeout(Duration::from_millis(1000))
      .expect("TestComponent1 never started!");
Source

fn stop(&self, c: &Arc<impl AbstractComponent + ?Sized>)

Stop a component

A component does not handle any events/messages while it is stopped, but it does not get deallocated either. It can be started again later with start or start_notify.

A component that is stopped shouldn’t be scheduled and thus access to its definition should always succeed, for example via on_definition.

§Example
use std::time::Duration;
let c = system.create(TestComponent1::new);
system.start_notify(&c)
      .wait_timeout(Duration::from_millis(1000))
      .expect("TestComponent1 never started!");
system.stop(&c);
Source

fn stop_notify(&self, c: &Arc<impl AbstractComponent + ?Sized>) -> KFuture<()>

Stop a component and complete a future once it has stopped

When the returned future completes, the component is guaranteed to have stopped. However, it is not guaranteed to be in a passive state, as it could already have been started again since.

A component does not handle any events/messages while it is stopped, but it does not get deallocated either. It can be started again later with start or start_notify.

A component that is stopped shouldn’t be scheduled and thus access to its definition should always succeed, for example via on_definition.

§Example
use std::time::Duration;
let c = system.create(TestComponent1::new);
system.start_notify(&c)
      .wait_timeout(Duration::from_millis(1000))
      .expect("TestComponent1 never started!");
system.stop_notify(&c)
      .wait_timeout(Duration::from_millis(1000))
      .expect("TestComponent1 never stopped!");
system.start_notify(&c)
      .wait_timeout(Duration::from_millis(1000))
      .expect("TestComponent1 never re-started!");
Source

fn kill(&self, c: Arc<impl AbstractComponent + ?Sized>)

Stop and deallocate a component

The supervisor will attempt to deallocate c once it is stopped. However, if there are still outstanding references somewhere else in the system this will fail, of course. In that case the supervisor leaves a debug message in the logging output, so that this circumstance can be discovered if necessary.

§Example
use std::time::Duration;
let c = system.create(TestComponent1::new);
system.start_notify(&c)
      .wait_timeout(Duration::from_millis(1000))
      .expect("TestComponent1 never started!");
system.kill(c);
Source

fn kill_notify(&self, c: Arc<impl AbstractComponent + ?Sized>) -> KFuture<()>

Stop and deallocate a component, and complete a future once it has stopped

The supervisor will attempt to deallocate c once it is stopped. However, if there are still outstanding references somewhere else in the system this will fail, of course. In that case the supervisor leaves a debug message in the logging output, so that this circumstance can be discovered if necessary.

§Note

The completion of the future indicates that the component has been stopped, not that it has been deallocated.

If, for some reason, you really need to know when it has been deallocated, you need to hold on to a copy of the component, use try_unwrap and then call drop once you are successful.

§Example
use std::time::Duration;
let c = system.create(TestComponent1::new);
system.start_notify(&c)
      .wait_timeout(Duration::from_millis(1000))
      .expect("TestComponent1 never started!");
system.kill_notify(c)
      .wait_timeout(Duration::from_millis(1000))
      .expect("TestComponent1 never stopped!");
Source

fn throughput(&self) -> usize

Return the configured thoughput value

See also throughput.

Source

fn max_messages(&self) -> usize

Return the configured maximum number of messages per scheduling

This value is based on throughput and msg_priority.

Source

fn shutdown_async(&self)

Start shutting down the Kompact system from within a component.

This is a fire-and-forget helper for lifecycle and message handlers that cannot consume their system handle. Use shutdown when you own the system and want to wait for shutdown to finish.

Shutdown may fail to stop in time (or at all), if components hang on to scheduler threads indefinitely.

§Example
use kompact::prelude::*;

#[derive(ComponentDefinition, Actor)]
struct Stopper {
   ctx: ComponentContext<Self>,
}
impl Stopper {
    fn new() -> Stopper {
        Stopper {
            ctx: ComponentContext::uninitialised(),
        }
    }
}
impl ComponentLifecycle for Stopper {
   fn on_start(&mut self) -> HandlerResult {
       self.ctx().system().shutdown_async();
       Handled::OK
    }
}
let system = KompactConfig::default().build().wait().expect("system");
let c = system.create(Stopper::new);
system.start(&c);
system.await_termination();
Source

fn deadletter_ref(&self) -> ActorRef<!>

Returns a reference to the system’s deadletter box

Source

fn spawn<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.

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§