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