Skip to content

Commit

Permalink
refactor(iroh): use boxed client to get rid of the C type parameter (#…
Browse files Browse the repository at this point in the history
…2353)

## Description

I implemented a boxed connection and a boxed service endpoint in
quic-rpc.

With this we can get rid of the `<C: ServiceConnection<RpcService>` type
parameter and make the quinn and mem client/server side the same type.

The nice thing about this approach is that it will not lead to additonal
boxing on the mem path, and for the quinn or whatever io path the boxing
will probably not matter that much compared to all the other things
going on.

## Breaking Changes

A lot. Iroh and all the clients no longer have `<C:
ServiceConnection<RpcService>`.

## Notes & open questions

Note: I marked the old type aliases MemIroh, QuicIroh etc as deprecated.
That does not seem to actually do anything, but just serves as a
reminder to remove them in the near future.

## Change checklist

- [x] Self-review.
- [x] Documentation updates if relevant.
~~- [x] Tests if relevant.~~
- [x] All breaking changes documented.
  • Loading branch information
rklaehn authored Jun 20, 2024
1 parent 55a0c0b commit cd43f18
Show file tree
Hide file tree
Showing 26 changed files with 134 additions and 261 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion iroh-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ parking_lot = "0.12.1"
pkarr = { version = "1.1.5", default-features = false }
portable-atomic = "1"
postcard = "1.0.8"
quic-rpc = { version = "0.10.0", features = ["flume-transport", "quinn-transport"] }
quic-rpc = { version = "0.10.2", features = ["flume-transport", "quinn-transport"] }
rand = "0.8.5"
ratatui = "0.26.2"
reqwest = { version = "0.12.4", default-features = false, features = ["json", "rustls-tls"] }
Expand Down
6 changes: 3 additions & 3 deletions iroh-cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
use anyhow::{ensure, Context, Result};
use clap::Parser;
use derive_more::FromStr;
use iroh::client::QuicIroh;
use iroh::client::Iroh;

use crate::config::{ConsoleEnv, NodeConfig};

Expand Down Expand Up @@ -130,7 +130,7 @@ impl Cli {
.await
} else {
crate::logging::init_terminal_logging()?;
let iroh = QuicIroh::connect(data_dir).await.context("rpc connect")?;
let iroh = Iroh::connect(data_dir).await.context("rpc connect")?;
let env = ConsoleEnv::for_console(data_dir_owned, &iroh).await?;
console::run(&iroh, &env).await
}
Expand All @@ -151,7 +151,7 @@ impl Cli {
.await
} else {
crate::logging::init_terminal_logging()?;
let iroh = QuicIroh::connect(data_dir).await.context("rpc connect")?;
let iroh = Iroh::connect(data_dir).await.context("rpc connect")?;
let env = ConsoleEnv::for_cli(data_dir_owned, &iroh).await?;
command.run(&iroh, &env).await
}
Expand Down
8 changes: 2 additions & 6 deletions iroh-cli/src/commands/author.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use derive_more::FromStr;
use futures_lite::StreamExt;
use iroh::base::base32::fmt_short;

use iroh::client::{Iroh, RpcService};
use iroh::client::Iroh;
use iroh::docs::{Author, AuthorId};
use quic_rpc::ServiceConnection;

use crate::config::ConsoleEnv;

Expand Down Expand Up @@ -38,10 +37,7 @@ pub enum AuthorCommands {
}

impl AuthorCommands {
pub async fn run<C>(self, iroh: &Iroh<C>, env: &ConsoleEnv) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
pub async fn run(self, iroh: &Iroh, env: &ConsoleEnv) -> Result<()> {
match self {
Self::Switch { author } => {
env.set_author(author)?;
Expand Down
36 changes: 10 additions & 26 deletions iroh-cli/src/commands/blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ use iroh::{
BlobInfo, BlobStatus, CollectionInfo, DownloadMode, DownloadOptions,
IncompleteBlobInfo, WrapOption,
},
Iroh, RpcService,
Iroh,
},
net::{key::PublicKey, relay::RelayUrl, NodeAddr},
};
use quic_rpc::ServiceConnection;
use tokio::io::AsyncWriteExt;

#[allow(clippy::large_enum_variant)]
Expand Down Expand Up @@ -182,10 +181,7 @@ impl std::str::FromStr for TicketOrHash {
}

impl BlobCommands {
pub async fn run<C>(self, iroh: &Iroh<C>) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
pub async fn run(self, iroh: &Iroh) -> Result<()> {
match self {
Self::Get {
ticket,
Expand Down Expand Up @@ -447,10 +443,7 @@ pub enum ListCommands {
}

impl ListCommands {
pub async fn run<C>(self, iroh: &Iroh<C>) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
pub async fn run(self, iroh: &Iroh) -> Result<()> {
match self {
Self::Blobs => {
let mut response = iroh.blobs().list().await?;
Expand Down Expand Up @@ -507,10 +500,7 @@ pub enum DeleteCommands {
}

impl DeleteCommands {
pub async fn run<C>(self, iroh: &Iroh<C>) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
pub async fn run(self, iroh: &Iroh) -> Result<()> {
match self {
Self::Blob { hash } => {
let response = iroh.blobs().delete_blob(hash).await;
Expand Down Expand Up @@ -540,10 +530,7 @@ fn apply_report_level(text: String, level: ReportLevel) -> console::StyledObject
}
}

pub async fn consistency_check<C>(iroh: &Iroh<C>, verbose: u8, repair: bool) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
pub async fn consistency_check(iroh: &Iroh, verbose: u8, repair: bool) -> Result<()> {
let mut response = iroh.blobs().consistency_check(repair).await?;
let verbosity = get_report_level(verbose);
let print = |level: ReportLevel, entry: Option<Hash>, message: String| {
Expand Down Expand Up @@ -584,10 +571,7 @@ where
Ok(())
}

pub async fn validate<C>(iroh: &Iroh<C>, verbose: u8, repair: bool) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
pub async fn validate(iroh: &Iroh, verbose: u8, repair: bool) -> Result<()> {
let mut state = ValidateProgressState::new();
let mut response = iroh.blobs().validate(repair).await?;
let verbosity = get_report_level(verbose);
Expand Down Expand Up @@ -807,8 +791,8 @@ pub enum TicketOption {
Print,
}

pub async fn add_with_opts<C: ServiceConnection<RpcService>>(
client: &iroh::client::Iroh<C>,
pub async fn add_with_opts(
client: &iroh::client::Iroh,
source: BlobSource,
opts: BlobAddOptions,
) -> Result<()> {
Expand Down Expand Up @@ -840,8 +824,8 @@ pub async fn add_with_opts<C: ServiceConnection<RpcService>>(
}

/// Add data to iroh, either from a path or, if path is `None`, from STDIN.
pub async fn add<C: ServiceConnection<RpcService>>(
client: &iroh::client::Iroh<C>,
pub async fn add(
client: &iroh::client::Iroh,
source: BlobSourceIroh,
tag: SetTagOption,
ticket: TicketOption,
Expand Down
8 changes: 2 additions & 6 deletions iroh-cli/src/commands/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use anyhow::Result;
use clap::{Parser, Subcommand};
use colored::Colorize;
use iroh::base::base32::fmt_short;
use iroh::client::{Iroh, RpcService};
use quic_rpc::ServiceConnection;
use iroh::client::Iroh;
use rustyline::{error::ReadlineError, Config, DefaultEditor};
use tokio::sync::{mpsc, oneshot};

Expand All @@ -12,10 +11,7 @@ use crate::{
config::{ConsoleEnv, ConsolePaths},
};

pub async fn run<C>(iroh: &Iroh<C>, env: &ConsoleEnv) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
pub async fn run(iroh: &Iroh, env: &ConsoleEnv) -> Result<()> {
println!("{}", "Welcome to the Iroh console!".purple().bold());
println!("Type `{}` for a list of commands.", "help".bold());
let mut from_repl = Repl::spawn(env.clone());
Expand Down
42 changes: 9 additions & 33 deletions iroh-cli/src/commands/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use dialoguer::Confirm;
use futures_buffered::BufferedStreamExt;
use futures_lite::{Stream, StreamExt};
use indicatif::{HumanBytes, HumanDuration, MultiProgress, ProgressBar, ProgressStyle};
use quic_rpc::ServiceConnection;
use tokio::io::AsyncReadExt;

use iroh::{
Expand All @@ -22,7 +21,7 @@ use iroh::{
client::{
blobs::WrapOption,
docs::{Doc, Entry, LiveEvent, Origin, ShareMode},
Iroh, RpcService,
Iroh,
},
docs::{
store::{DownloadPolicy, FilterKind, Query, SortDirection},
Expand Down Expand Up @@ -303,10 +302,7 @@ impl From<Sorting> for iroh::docs::store::SortBy {
}

impl DocCommands {
pub async fn run<C>(self, iroh: &Iroh<C>, env: &ConsoleEnv) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
pub async fn run(self, iroh: &Iroh, env: &ConsoleEnv) -> Result<()> {
match self {
Self::Switch { id: doc } => {
env.set_doc(doc)?;
Expand Down Expand Up @@ -673,29 +669,15 @@ impl DocCommands {
}
}

async fn get_doc<C>(
iroh: &Iroh<C>,
env: &ConsoleEnv,
id: Option<NamespaceId>,
) -> anyhow::Result<Doc<C>>
where
C: ServiceConnection<RpcService>,
{
async fn get_doc(iroh: &Iroh, env: &ConsoleEnv, id: Option<NamespaceId>) -> anyhow::Result<Doc> {
iroh.docs()
.open(env.doc(id)?)
.await?
.context("Document not found")
}

/// Format the content. If an error occurs it's returned in a formatted, friendly way.
async fn fmt_content<C>(
doc: &Doc<C>,
entry: &Entry,
mode: DisplayContentMode,
) -> Result<String, String>
where
C: ServiceConnection<RpcService>,
{
async fn fmt_content(doc: &Doc, entry: &Entry, mode: DisplayContentMode) -> Result<String, String> {
let read_failed = |err: anyhow::Error| format!("<failed to get content: {err}>");
let encode_hex = |err: std::string::FromUtf8Error| format!("0x{}", hex::encode(err.as_bytes()));
let as_utf8 = |buf: Vec<u8>| String::from_utf8(buf).map(|repr| format!("\"{repr}\""));
Expand Down Expand Up @@ -743,10 +725,7 @@ fn human_len(entry: &Entry) -> HumanBytes {
}

#[must_use = "this won't be printed, you need to print it yourself"]
async fn fmt_entry<C>(doc: &Doc<C>, entry: &Entry, mode: DisplayContentMode) -> String
where
C: ServiceConnection<RpcService>,
{
async fn fmt_entry(doc: &Doc, entry: &Entry, mode: DisplayContentMode) -> String {
let key = std::str::from_utf8(entry.key())
.unwrap_or("<bad key>")
.bold();
Expand Down Expand Up @@ -776,18 +755,15 @@ fn tag_from_file_name(path: &Path) -> anyhow::Result<Tag> {
/// document via the hash of the blob.
/// It also creates and powers the `ImportProgressBar`.
#[tracing::instrument(skip_all)]
async fn import_coordinator<C>(
doc: Doc<C>,
async fn import_coordinator(
doc: Doc,
author_id: AuthorId,
root: PathBuf,
prefix: String,
blob_add_progress: impl Stream<Item = Result<AddProgress>> + Send + Unpin + 'static,
expected_size: u64,
expected_entries: u64,
) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
) -> Result<()> {
let imp = ImportProgressBar::new(
&root.display().to_string(),
doc.id(),
Expand Down Expand Up @@ -982,7 +958,7 @@ mod tests {
let cli = ConsoleEnv::for_console(data_dir.path().to_owned(), &node)
.await
.context("ConsoleEnv")?;
let iroh = iroh::client::QuicIroh::connect(data_dir.path())
let iroh = iroh::client::Iroh::connect(data_dir.path())
.await
.context("rpc connect")?;

Expand Down
7 changes: 1 addition & 6 deletions iroh-cli/src/commands/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ use comfy_table::{presets::NOTHING, Cell};
use futures_lite::{Stream, StreamExt};
use human_time::ToHumanTimeString;
use iroh::client::Iroh;
use iroh::client::RpcService;
use iroh::net::{
endpoint::{ConnectionInfo, DirectAddrInfo},
key::PublicKey,
};
use quic_rpc::ServiceConnection;

#[derive(Subcommand, Debug, Clone)]
#[allow(clippy::large_enum_variant)]
Expand All @@ -38,10 +36,7 @@ pub enum NodeCommands {
}

impl NodeCommands {
pub async fn run<C>(self, iroh: &Iroh<C>) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
pub async fn run(self, iroh: &Iroh) -> Result<()> {
match self {
Self::Connections => {
let connections = iroh.connections().await?;
Expand Down
8 changes: 2 additions & 6 deletions iroh-cli/src/commands/rpc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use anyhow::Result;
use clap::Subcommand;
use iroh::client::{Iroh, RpcService};
use quic_rpc::ServiceConnection;
use iroh::client::Iroh;

use crate::config::ConsoleEnv;

Expand Down Expand Up @@ -58,10 +57,7 @@ pub enum RpcCommands {
}

impl RpcCommands {
pub async fn run<C>(self, iroh: &Iroh<C>, env: &ConsoleEnv) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
pub async fn run(self, iroh: &Iroh, env: &ConsoleEnv) -> Result<()> {
match self {
Self::Node { command } => command.run(iroh).await,
Self::Blob { command } => command.run(iroh).await,
Expand Down
4 changes: 2 additions & 2 deletions iroh-cli/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub async fn run_with_command<F, T>(
command: F,
) -> Result<()>
where
F: FnOnce(iroh::client::MemIroh) -> T + Send + 'static,
F: FnOnce(iroh::client::Iroh) -> T + Send + 'static,
T: Future<Output = Result<()>> + 'static,
{
let _guard = crate::logging::init_terminal_and_file_logging(&config.file_logs, iroh_data_root)?;
Expand Down Expand Up @@ -68,7 +68,7 @@ async fn run_with_command_inner<F, T>(
command: F,
) -> Result<()>
where
F: FnOnce(iroh::client::MemIroh) -> T + Send + 'static,
F: FnOnce(iroh::client::Iroh) -> T + Send + 'static,
T: Future<Output = Result<()>> + 'static,
{
let relay_map = config.relay_map()?;
Expand Down
8 changes: 2 additions & 6 deletions iroh-cli/src/commands/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use bytes::Bytes;
use clap::Subcommand;
use futures_lite::StreamExt;
use iroh::blobs::Tag;
use iroh::client::{Iroh, RpcService};
use quic_rpc::ServiceConnection;
use iroh::client::Iroh;

#[derive(Subcommand, Debug, Clone)]
#[allow(clippy::large_enum_variant)]
Expand All @@ -20,10 +19,7 @@ pub enum TagCommands {
}

impl TagCommands {
pub async fn run<C>(self, iroh: &Iroh<C>) -> Result<()>
where
C: ServiceConnection<RpcService>,
{
pub async fn run(self, iroh: &Iroh) -> Result<()> {
match self {
Self::List => {
let mut response = iroh.tags().list().await?;
Expand Down
Loading

0 comments on commit cd43f18

Please sign in to comment.