commonware_collector/
lib.rs

1//! Collect responses to [Committable] requests.
2//!
3//! # Status
4//!
5//! `commonware-collector` is **ALPHA** software and is not yet recommended for production use. Developers should
6//! expect breaking changes and occasional instability.
7
8#![doc(
9    html_logo_url = "https://commonware.xyz/imgs/rustdoc_logo.svg",
10    html_favicon_url = "https://commonware.xyz/favicon.ico"
11)]
12
13use commonware_codec::Codec;
14use commonware_cryptography::{Committable, Digestible, PublicKey};
15use commonware_p2p::Recipients;
16use futures::channel::oneshot;
17use std::future::Future;
18use thiserror::Error;
19
20pub mod p2p;
21
22/// Errors that can occur when interacting with a [Originator].
23#[derive(Error, Debug)]
24pub enum Error {
25    #[error("send failed: {0}")]
26    SendFailed(anyhow::Error),
27    #[error("canceled")]
28    Canceled,
29}
30
31/// An [Originator] sends requests out to a set of [Handler]s and collects replies.
32pub trait Originator: Clone + Send + 'static {
33    /// The [PublicKey] of a recipient.
34    type PublicKey: PublicKey;
35
36    /// The type of request to send.
37    type Request: Committable + Digestible + Codec;
38
39    /// Sends a `Request` to a set of [Recipients], returning the list of handlers that we
40    /// tried to send to.
41    fn send(
42        &mut self,
43        recipients: Recipients<Self::PublicKey>,
44        request: Self::Request,
45    ) -> impl Future<Output = Result<Vec<Self::PublicKey>, Error>> + Send;
46
47    /// Cancel a request by `commitment`, ignoring any future responses.
48    ///
49    /// Tracked commitments are not removed until explicitly cancelled.
50    fn cancel(
51        &mut self,
52        commitment: <Self::Request as Committable>::Commitment,
53    ) -> impl Future<Output = ()> + Send;
54}
55
56/// A [Handler] receives requests and (optionally) sends replies.
57pub trait Handler: Clone + Send + 'static {
58    /// The [PublicKey] of the [Originator].
59    type PublicKey: PublicKey;
60
61    /// The type of request received.
62    type Request: Committable + Digestible + Codec;
63
64    /// The type of response to send.
65    type Response: Committable<Commitment = <Self::Request as Committable>::Commitment>
66        + Digestible<Digest = <Self::Request as Digestible>::Digest>
67        + Codec;
68
69    /// Processes a `request` from an [Originator] and (optionally) send a response.
70    ///
71    /// If no response is needed, the `responder` should be dropped.
72    fn process(
73        &mut self,
74        origin: Self::PublicKey,
75        request: Self::Request,
76        response: oneshot::Sender<Self::Response>,
77    ) -> impl Future<Output = ()> + Send;
78}
79
80/// A [Monitor] collects responses from [Handler]s.
81pub trait Monitor: Clone + Send + 'static {
82    /// The [PublicKey] of the [Handler].
83    type PublicKey: PublicKey;
84
85    /// The type of response collected.
86    type Response: Committable + Digestible + Codec;
87
88    /// Called for each response collected with the number of responses collected so far for
89    /// the same commitment.
90    ///
91    /// [Monitor::collected] is only called once per `handler`.
92    fn collected(
93        &mut self,
94        handler: Self::PublicKey,
95        response: Self::Response,
96        count: usize,
97    ) -> impl Future<Output = ()> + Send;
98}