1
//! Module exposing the [`ChannelProvider`] trait.
2
//!
3
//! Relay circuit reactors use a [`ChannelProvider`] to open outgoing channels.
4

            
5
use crate::Result;
6
use crate::channel::Channel;
7
use crate::circuit::UniqId;
8

            
9
use async_trait::async_trait;
10
use futures::channel::mpsc;
11

            
12
use std::sync::Arc;
13

            
14
use tor_linkspec::HasRelayIds;
15

            
16
/// A channel result returned by a [`ChannelProvider`].
17
pub type ChannelResult = Result<Arc<Channel>>;
18

            
19
/// A sender for returning an outgoing relay channel
20
/// requested via [`ChannelProvider::get_or_launch`].
21
//
22
// Note: this channel is unbounded, because the limit should be imposed
23
// by the [`ChannelProvider`].
24
pub struct OutboundChanSender(pub(crate) mpsc::UnboundedSender<ChannelResult>);
25

            
26
impl OutboundChanSender {
27
    /// Create a new [`OutboundChanSender`] from an [`mpsc`] sender.
28
    ///
29
    /// This should remain crate-private, as these senders
30
    /// should only ever be created by the relay circuit reactor
31
    /// to request a new outbound channel.
32
    #[allow(dead_code)] // TODO(relay)
33
    pub(crate) fn new(tx: mpsc::UnboundedSender<ChannelResult>) -> Self {
34
        Self(tx)
35
    }
36

            
37
    /// Send the specified channel result to the requester.
38
    ///
39
    /// See [`ChannelProvider::get_or_launch`].
40
    pub fn send(self, result: ChannelResult) {
41
        // Don't care if the receiver goes away
42
        let _ = self.0.unbounded_send(result);
43
    }
44
}
45

            
46
/// An object that can fulfill outbound channel requests
47
/// issued by the relay circuit reactor.
48
///
49
/// The implementor is responsible for imposing a limit on the
50
/// number of outbound channels that can be opened on a given circuit.
51
#[async_trait]
52
pub trait ChannelProvider {
53
    /// Type that explains how to build an outgoing channel.
54
    type BuildSpec: HasRelayIds;
55

            
56
    /// Get a channel corresponding to the identities of `target`, for the circuit reactor with the
57
    /// specified `reactor_id` which should only be used for logging purposes.
58
    ///
59
    /// Returns the requested channel via the specified [`OutboundChanSender`].
60
    fn get_or_launch(
61
        self: Arc<Self>,
62
        reactor_id: UniqId,
63
        target: Self::BuildSpec,
64
        tx: OutboundChanSender,
65
    ) -> Result<()>;
66
}