-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat!: Add Docs<S> which wraps the Engine<S> (#18)
* Add Docs<S> which wraps the Engine<S> The ProtocolHandler is now implemented only for Blobs<S>. Docs<S> has a builder that takes a Blobs<S> and Gossip<S>, but there is also a way to create a Docs directly from an Engine. * feature gate the Docs<S> and its builder * use the gossip builder API * add net feature * remove top level feature flag * Make Engine !Clone and remove a few nested arcs. * fully qualify all the things * more feature flag madness
- Loading branch information
Showing
7 changed files
with
148 additions
and
75 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,127 @@ | ||
//! [`ProtocolHandler`] implementation for the docs [`Engine`]. | ||
use std::{path::PathBuf, sync::Arc}; | ||
|
||
use anyhow::Result; | ||
use futures_lite::future::Boxed as BoxedFuture; | ||
use iroh::{endpoint::Connecting, protocol::ProtocolHandler}; | ||
use iroh_blobs::net_protocol::{Blobs, ProtectCb}; | ||
use iroh_gossip::net::Gossip; | ||
|
||
use crate::engine::Engine; | ||
use crate::{ | ||
engine::{DefaultAuthorStorage, Engine}, | ||
store::Store, | ||
}; | ||
|
||
impl<D: iroh_blobs::store::Store> ProtocolHandler for Engine<D> { | ||
impl<S: iroh_blobs::store::Store> ProtocolHandler for Docs<S> { | ||
fn accept(&self, conn: Connecting) -> BoxedFuture<Result<()>> { | ||
let this = self.clone(); | ||
let this = self.engine.clone(); | ||
Box::pin(async move { this.handle_connection(conn).await }) | ||
} | ||
|
||
fn shutdown(&self) -> BoxedFuture<()> { | ||
let this = self.clone(); | ||
let this = self.engine.clone(); | ||
Box::pin(async move { | ||
if let Err(err) = this.shutdown().await { | ||
tracing::warn!("shutdown error: {:?}", err); | ||
} | ||
}) | ||
} | ||
} | ||
|
||
/// Docs protocol. | ||
#[derive(Debug, Clone)] | ||
pub struct Docs<S> { | ||
engine: Arc<Engine<S>>, | ||
#[cfg(feature = "rpc")] | ||
pub(crate) rpc_handler: Arc<std::sync::OnceLock<crate::rpc::RpcHandler>>, | ||
} | ||
|
||
impl Docs<()> { | ||
/// Create a new [`Builder`] for the docs protocol, using in memory replica and author storage. | ||
pub fn memory() -> Builder { | ||
Builder::default() | ||
} | ||
|
||
/// Create a new [`Builder`] for the docs protocol, using a persistent replica and author storage | ||
/// in the given directory. | ||
pub fn persistent(path: PathBuf) -> Builder { | ||
Builder { path: Some(path) } | ||
} | ||
} | ||
|
||
impl<S: iroh_blobs::store::Store> Docs<S> { | ||
/// Get an in memory client to interact with the docs engine. | ||
#[cfg(feature = "rpc")] | ||
pub fn client(&self) -> &crate::rpc::client::docs::MemClient { | ||
&self | ||
.rpc_handler | ||
.get_or_init(|| crate::rpc::RpcHandler::new(self.engine.clone())) | ||
.client | ||
} | ||
|
||
/// Create a new docs protocol with the given engine. | ||
/// | ||
/// Note that usually you would use the [`Builder`] to create a new docs protocol. | ||
pub fn new(engine: Engine<S>) -> Self { | ||
Self { | ||
engine: Arc::new(engine), | ||
#[cfg(feature = "rpc")] | ||
rpc_handler: Default::default(), | ||
} | ||
} | ||
|
||
/// Handle a docs request from the RPC server. | ||
#[cfg(feature = "rpc")] | ||
pub async fn handle_rpc_request< | ||
C: quic_rpc::server::ChannelTypes<crate::rpc::proto::RpcService>, | ||
>( | ||
self, | ||
msg: crate::rpc::proto::Request, | ||
chan: quic_rpc::server::RpcChannel<crate::rpc::proto::RpcService, C>, | ||
) -> Result<(), quic_rpc::server::RpcServerError<C>> { | ||
crate::rpc::Handler(self.engine.clone()) | ||
.handle_rpc_request(msg, chan) | ||
.await | ||
} | ||
|
||
/// Get the protect callback for the docs engine. | ||
pub fn protect_cb(&self) -> ProtectCb { | ||
self.engine.protect_cb() | ||
} | ||
} | ||
|
||
/// Builder for the docs protocol. | ||
#[derive(Debug, Default)] | ||
pub struct Builder { | ||
path: Option<PathBuf>, | ||
} | ||
|
||
impl Builder { | ||
/// Build a [`Docs`] protocol given a [`Blobs`] and [`Gossip`] protocol. | ||
pub async fn spawn<S: iroh_blobs::store::Store>( | ||
self, | ||
blobs: &Blobs<S>, | ||
gossip: &Gossip, | ||
) -> anyhow::Result<Docs<S>> { | ||
let replica_store = match self.path { | ||
Some(ref path) => Store::persistent(path.join("docs.redb"))?, | ||
None => Store::memory(), | ||
}; | ||
let author_store = match self.path { | ||
Some(ref path) => DefaultAuthorStorage::Persistent(path.join("default-author")), | ||
None => DefaultAuthorStorage::Mem, | ||
}; | ||
let engine = Engine::spawn( | ||
blobs.endpoint().clone(), | ||
gossip.clone(), | ||
replica_store, | ||
blobs.store().clone(), | ||
blobs.downloader().clone(), | ||
author_store, | ||
blobs.rt().clone(), | ||
) | ||
.await?; | ||
Ok(Docs::new(engine)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters