bee_runtime/node.rs
1// Copyright 2020-2021 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4//! Traits used to represent bee nodes and allow for their instantiation.
5
6use std::any::Any;
7
8use async_trait::async_trait;
9use bee_storage::backend::StorageBackend;
10use futures::{channel::oneshot, future::Future};
11
12use crate::{event::Bus, resource::ResourceHandle, worker::Worker};
13
14/// A type holding information about a node.
15pub struct NodeInfo {
16 /// Name of the node.
17 pub name: String,
18 /// Version of the node.
19 pub version: String,
20}
21
22/// A trait representing a node framework through which node workers may communicate.
23#[async_trait]
24pub trait Node: Send + Sized + 'static {
25 /// The builder type used to create instances of this node.
26 type Builder: NodeBuilder<Self>;
27 /// The storage backend used by this node.
28 type Backend: StorageBackend;
29 /// The type of errors that may be emitted as a result of the build process.
30 type Error: std::error::Error;
31
32 /// Stop the node, ending the execution of all workers in a timely manner.
33 async fn stop(mut self) -> Result<(), Self::Error>;
34
35 /// Spawn a new node task associated with the given worker.
36 ///
37 /// The task will be shut down with the worker to preserve topological worker ordering.
38 fn spawn<W, G, F>(&mut self, g: G)
39 where
40 W: Worker<Self>,
41 G: FnOnce(oneshot::Receiver<()>) -> F,
42 F: Future<Output = ()> + Send + 'static;
43
44 /// Get a reference to the state of a worker.
45 fn worker<W>(&self) -> Option<&W>
46 where
47 W: Worker<Self> + Send + Sync;
48
49 /// Register a new resource with the node such that other workers may access it via [`Node::resource`].
50 fn register_resource<R: Any + Send + Sync>(&mut self, res: R);
51
52 /// Attempt to remove a resource from the node, returning `None` if no such resource was registered with the node.
53 fn remove_resource<R: Any + Send + Sync>(&mut self) -> Option<R>;
54
55 /// Obtain an owning handle to a node resource.
56 #[track_caller]
57 fn resource<R: Any + Send + Sync>(&self) -> ResourceHandle<R>;
58
59 /// Obtain an owning handle to the node's info.
60 #[track_caller]
61 fn info(&self) -> ResourceHandle<NodeInfo> {
62 self.resource()
63 }
64
65 /// Obtain an owning handle to the node's storage backend.
66 #[track_caller]
67 fn storage(&self) -> ResourceHandle<Self::Backend> {
68 self.resource()
69 }
70
71 /// Obtain an owning handle to the node's event bus.
72 #[track_caller]
73 fn bus(&self) -> ResourceHandle<Bus<'static>> {
74 self.resource()
75 }
76}
77
78/// A trait that provides generic build configuration capabilities for a node.
79#[async_trait(?Send)]
80pub trait NodeBuilder<N: Node>: Sized {
81 /// The type of errors that may be emitted as a result of the build process.
82 type Error: std::error::Error;
83 /// Global configuration provided to the node on creation.
84 type Config;
85
86 /// Begin building a new node with the provided configuration state.
87 fn new(config: Self::Config) -> Result<Self, Self::Error>;
88
89 /// Register a worker, with default configuration state, that should be started with the node.
90 #[must_use]
91 fn with_worker<W: Worker<N> + 'static>(self) -> Self
92 where
93 W::Config: Default;
94
95 /// Register a worker, with the given configuration state, that should be started with the node.
96 #[must_use]
97 fn with_worker_cfg<W: Worker<N> + 'static>(self, config: W::Config) -> Self;
98
99 /// Provide a resource that should be registered with the node upon start.
100 #[must_use]
101 fn with_resource<R: Any + Send + Sync>(self, res: R) -> Self;
102
103 /// Finish building the node, returning the final node.
104 async fn finish(self) -> Result<N, Self::Error>;
105}