Skip to content

Commit 24ccc21

Browse files
committed
docs: Write missing documentation in iroh/src/protocol.rs
1 parent 35a1724 commit 24ccc21

File tree

1 file changed

+87
-11
lines changed

1 file changed

+87
-11
lines changed

iroh/src/protocol.rs

Lines changed: 87 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,44 @@
1-
//! TODO(matheus23) docs
1+
//! Tools for spawning an accept loop that routes incoming requests to the right protocol.
2+
//!
3+
//! ## Example
4+
//!
5+
//! ```no_run
6+
//! # use std::sync::Arc;
7+
//! # use anyhow::Result;
8+
//! # use futures_lite::future::Boxed as BoxedFuture;
9+
//! # use iroh::{endpoint::Connecting, protocol::{ProtocolHandler, Router}, Endpoint, NodeAddr};
10+
//! #
11+
//! # async fn test_compile() -> Result<()> {
12+
//! let endpoint = Endpoint::builder().discovery_n0().bind().await?;
13+
//!
14+
//! let router = Router::builder(endpoint)
15+
//! .accept(ALPN.to_vec(), Arc::new(Echo))
16+
//! .spawn()
17+
//! .await?;
18+
//! # Ok(())
19+
//! # }
20+
//!
21+
//! // The protocol definition:
22+
//! #[derive(Debug, Clone)]
23+
//! struct Echo;
24+
//!
25+
//! impl ProtocolHandler for Echo {
26+
//! fn accept(self: Arc<Self>, connecting: Connecting) -> BoxedFuture<Result<()>> {
27+
//! Box::pin(async move {
28+
//! let connection = connecting.await?;
29+
//! let (mut send, mut recv) = connection.accept_bi().await?;
30+
//!
31+
//! // Echo any bytes received back directly.
32+
//! let bytes_sent = tokio::io::copy(&mut recv, &mut send).await?;
33+
//!
34+
//! send.finish()?;
35+
//! connection.closed().await;
36+
//!
37+
//! Ok(())
38+
//! })
39+
//! }
40+
//! }
41+
//! ```
242
use std::{any::Any, collections::BTreeMap, sync::Arc};
343

444
use anyhow::{anyhow, Result};
@@ -14,7 +54,39 @@ use tracing::{debug, error, warn};
1454

1555
use crate::{endpoint::Connecting, Endpoint};
1656

17-
/// TODO(matheus23): docs
57+
/// The built router.
58+
///
59+
/// Construct this using [`Router::builder`].
60+
///
61+
/// When dropped, this will abort listening the tasks, so make sure to store it.
62+
///
63+
/// Even with this abort-on-drop behaviour, it's recommended to call and await
64+
/// [`Router::shutdown`] before ending the process.
65+
///
66+
/// As an example for graceful shutdown, e.g. for tests or CLI tools,
67+
/// wait for [`tokio::signal::ctrl_c()`]:
68+
///
69+
/// ```no_run
70+
/// # use std::sync::Arc;
71+
/// # use anyhow::Result;
72+
/// # use futures_lite::future::Boxed as BoxedFuture;
73+
/// # use iroh::{endpoint::Connecting, protocol::ProtocolHandler, router::Router, Endpoint, NodeAddr};
74+
/// #
75+
/// # async fn test_compile() -> Result<()> {
76+
/// let endpoint = Endpoint::builder().discovery_n0().bind().await?;
77+
///
78+
/// let router = Router::builder(endpoint)
79+
/// // .accept(ALPN.to_vec(), <something>)
80+
/// .spawn()
81+
/// .await?;
82+
///
83+
/// // wait until the user wants to
84+
/// tokio::signal::ctrl_c().await?;
85+
/// router.shutdown().await?;
86+
/// # Ok(())
87+
/// # }
88+
///
89+
/// ```
1890
#[derive(Clone, Debug)]
1991
pub struct Router {
2092
endpoint: Endpoint,
@@ -31,7 +103,7 @@ pub struct Router {
31103

32104
type JoinErrToStr = Box<dyn Fn(JoinError) -> String + Send + Sync + 'static>;
33105

34-
/// TODO(matheus23): docs
106+
/// Builder for creating a [`Router`] for accepting protocols.
35107
#[derive(Debug)]
36108
pub struct RouterBuilder {
37109
endpoint: Endpoint,
@@ -46,7 +118,7 @@ pub struct RouterBuilder {
46118
///
47119
/// Implement this trait on a struct that should handle incoming connections.
48120
/// The protocol handler must then be registered on the node for an ALPN protocol with
49-
/// [`crate::router::RouterBuilder::accept`].
121+
/// [`crate::protocol::RouterBuilder::accept`].
50122
pub trait ProtocolHandler: Send + Sync + IntoArcAny + std::fmt::Debug + 'static {
51123
/// Handle an incoming connection.
52124
///
@@ -63,7 +135,7 @@ pub trait ProtocolHandler: Send + Sync + IntoArcAny + std::fmt::Debug + 'static
63135
///
64136
/// This trait has a blanket implementation so there is no need to implement this yourself.
65137
pub trait IntoArcAny {
66-
/// TODO(matheus23): docs
138+
/// Casts `Arc<Self>` into `Arc<dyn Any + Send + Sync>`.
67139
fn into_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>;
68140
}
69141

@@ -111,7 +183,7 @@ impl ProtocolMap {
111183
}
112184

113185
impl Router {
114-
/// TODO(matheus23): docs
186+
/// Creates a new [`Router`] using given [`Endpoint`].
115187
pub fn builder(endpoint: Endpoint) -> RouterBuilder {
116188
RouterBuilder::new(endpoint)
117189
}
@@ -124,12 +196,15 @@ impl Router {
124196
self.protocols.get_typed(alpn)
125197
}
126198

127-
/// TODO(matheus23): docs
199+
/// Returns the [`Endpoint`] stored in this router.
128200
pub fn endpoint(&self) -> &Endpoint {
129201
&self.endpoint
130202
}
131203

132-
/// TODO(matheus23): docs
204+
/// Shuts down the accept loop cleanly.
205+
///
206+
/// If some [`ProtocolHandler`] paniced in the accept loop, this will propagate
207+
/// that panic into the result here.
133208
pub async fn shutdown(self) -> Result<()> {
134209
// Trigger shutdown of the main run task by activating the cancel token.
135210
self.cancel_token.cancel();
@@ -142,15 +217,16 @@ impl Router {
142217
}
143218

144219
impl RouterBuilder {
145-
/// TODO(matheus23): docs
220+
/// Creates a new router builder using given [`Endpoint`].
146221
pub fn new(endpoint: Endpoint) -> Self {
147222
Self {
148223
endpoint,
149224
protocols: ProtocolMap::default(),
150225
}
151226
}
152227

153-
/// TODO(matheus23): docs
228+
/// Configures the router to accept the [`ProtocolHandler`] when receiving a connection
229+
/// with this `alpn`.
154230
pub fn accept(mut self, alpn: impl AsRef<[u8]>, handler: Arc<dyn ProtocolHandler>) -> Self {
155231
self.protocols.insert(alpn.as_ref().to_vec(), handler);
156232
self
@@ -169,7 +245,7 @@ impl RouterBuilder {
169245
self.protocols.get_typed(alpn)
170246
}
171247

172-
/// TODO(matheus23): docs
248+
/// Spawns an accept loop and returns a handle to it encapsulated as the [`Router`].
173249
pub async fn spawn(self) -> Result<Router> {
174250
// Update the endpoint with our alpns.
175251
let alpns = self

0 commit comments

Comments
 (0)