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§
Sourcefn create<C, F>(&self, f: F) -> Arc<Component<C>>where
F: FnOnce() -> C,
C: ComponentDefinition + 'static,
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);Sourcefn start(&self, c: &Arc<impl AbstractComponent + ?Sized>)
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);Sourcefn start_notify(&self, c: &Arc<impl AbstractComponent + ?Sized>) -> KFuture<()> ⓘ
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!");Sourcefn stop(&self, c: &Arc<impl AbstractComponent + ?Sized>)
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);Sourcefn stop_notify(&self, c: &Arc<impl AbstractComponent + ?Sized>) -> KFuture<()> ⓘ
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!");Sourcefn kill(&self, c: Arc<impl AbstractComponent + ?Sized>)
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);Sourcefn kill_notify(&self, c: Arc<impl AbstractComponent + ?Sized>) -> KFuture<()> ⓘ
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!");Sourcefn throughput(&self) -> usize
fn throughput(&self) -> usize
Return the configured thoughput value
See also throughput.
Sourcefn max_messages(&self) -> usize
fn max_messages(&self) -> usize
Return the configured maximum number of messages per scheduling
This value is based on throughput and msg_priority.
Sourcefn shutdown_async(&self)
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();Sourcefn deadletter_ref(&self) -> ActorRef<!>
fn deadletter_ref(&self) -> ActorRef<!>
Returns a reference to the system’s deadletter box
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.