Skip to content

Commit

Permalink
refactor(iroh)!: convert node to net module (#2642)
Browse files Browse the repository at this point in the history
## Description

Converts the `node` module to the `net` module (`iroh` and `iroh-cli`)

Closes #2639

## Breaking Changes

- No more `deref` of `iroh::net::Client` to `iroh::client::node::Node`
- `iroh::client::node` -> `iroh::client::net`
- `iroh::client::node::Node::shutdown` ->
`iroh::client::Client::shutdown`

## Notes & open questions

<!-- Any notes, remarks or open questions you have to make about the PR.
-->

## Change checklist

- [x] Self-review.
- [x] Documentation updates following the [style
guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text),
if relevant.
- [ ] Tests if relevant.
- [x] All breaking changes documented.

---------

Co-authored-by: Kasey <[email protected]>
  • Loading branch information
dignifiedquire and ramfox authored Aug 19, 2024
1 parent d1578ee commit 6354e04
Show file tree
Hide file tree
Showing 17 changed files with 233 additions and 248 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
with:
distribution: 'temurin'
java-version: '17'

- name: Setup Android SDK
uses: android-actions/setup-android@v3

Expand All @@ -111,7 +111,7 @@ jobs:
- name: Build
env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
run: |
run: |
cargo install --version 3.5.4 cargo-ndk
cargo ndk --target ${{ matrix.target }} build
Expand Down Expand Up @@ -446,11 +446,11 @@ jobs:
target: iroh
platforms: linux/amd64
file: docker/Dockerfile
- name: Run Docker image & node stats test

- name: Run Docker image & stats test
run: |
docker run -p 9090:9090 -p 4919:4919/udp -Pd n0computer/iroh-test:latest --rpc-addr 0.0.0.0:4919 start
cargo run --bin iroh -- --rpc-addr 127.0.0.1:4919 node stats
cargo run --bin iroh -- --rpc-addr 127.0.0.1:4919 stats
codespell:
runs-on: ubuntu-latest
Expand Down
3 changes: 2 additions & 1 deletion iroh-cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub(crate) mod console;
pub(crate) mod docs;
pub(crate) mod doctor;
pub(crate) mod gossip;
pub(crate) mod node;
pub(crate) mod net;
pub(crate) mod rpc;
pub(crate) mod start;
pub(crate) mod tags;
Expand Down Expand Up @@ -190,6 +190,7 @@ impl Cli {
)
.await
}

Commands::Doctor { command } => {
let config = Self::load_config(self.config, self.metrics_addr).await?;
self::doctor::run(command, &config).await
Expand Down
48 changes: 7 additions & 41 deletions iroh-cli/src/commands/node.rs → iroh-cli/src/commands/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,11 @@ use iroh::net::{NodeAddr, NodeId};

#[derive(Subcommand, Debug, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum NodeCommands {
pub enum NetCommands {
/// Get information about the different remote nodes.
RemoteList,
/// Get information about a particular remote node.
Remote { node_id: NodeId },
/// Get status of the running node.
Status,
/// Get statistics and metrics from the running node.
Stats,
/// Shutdown the running node.
Shutdown {
/// Shutdown mode.
///
/// Hard shutdown will immediately terminate the process, soft shutdown will wait
/// for all connections to close.
#[clap(long, default_value_t = false)]
force: bool,
},
/// Get the node addr of this node.
NodeAddr,
/// Add this node addr to the known nodes.
Expand All @@ -45,11 +32,11 @@ pub enum NodeCommands {
HomeRelay,
}

impl NodeCommands {
impl NetCommands {
pub async fn run(self, iroh: &Iroh) -> Result<()> {
match self {
Self::RemoteList => {
let connections = iroh.remote_info_iter().await?;
let connections = iroh.net().remote_info_iter().await?;
let timestamp = time::OffsetDateTime::now_utc()
.format(&time::format_description::well_known::Rfc2822)
.unwrap_or_else(|_| String::from("failed to get current time"));
Expand All @@ -62,35 +49,14 @@ impl NodeCommands {
);
}
Self::Remote { node_id } => {
let info = iroh.remote_info(node_id).await?;
let info = iroh.net().remote_info(node_id).await?;
match info {
Some(info) => println!("{}", fmt_info(info)),
None => println!("Not Found"),
}
}
Self::Shutdown { force } => {
iroh.shutdown(force).await?;
}
Self::Stats => {
let stats = iroh.stats().await?;
for (name, details) in stats.iter() {
println!(
"{:23} : {:>6} ({})",
name, details.value, details.description
);
}
}
Self::Status => {
let response = iroh.status().await?;
println!("Listening addresses: {:#?}", response.listen_addrs);
println!("Node ID: {}", response.addr.node_id);
println!("Version: {}", response.version);
if let Some(addr) = response.rpc_addr {
println!("RPC Addr: {}", addr);
}
}
Self::NodeAddr => {
let addr = iroh.node_addr().await?;
let addr = iroh.net().node_addr().await?;
println!("Node ID: {}", addr.node_id);
let relay = addr
.info
Expand All @@ -112,10 +78,10 @@ impl NodeCommands {
if let Some(relay) = relay {
addr = addr.with_relay_url(relay);
}
iroh.add_node_addr(addr).await?;
iroh.net().add_node_addr(addr).await?;
}
Self::HomeRelay => {
let relay = iroh.home_relay().await?;
let relay = iroh.net().home_relay().await?;
let relay = relay
.map(|s| s.to_string())
.unwrap_or_else(|| "Not Available".to_string());
Expand Down
48 changes: 43 additions & 5 deletions iroh-cli/src/commands/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::config::ConsoleEnv;

use super::{
authors::AuthorCommands, blobs::BlobCommands, docs::DocCommands, gossip::GossipCommands,
node::NodeCommands, tags::TagCommands,
net::NetCommands, tags::TagCommands,
};

#[derive(Subcommand, Debug, Clone)]
Expand Down Expand Up @@ -42,10 +42,10 @@ pub enum RpcCommands {
#[clap(subcommand)]
command: BlobCommands,
},
/// Manage a running iroh node
Node {
/// Manage the iroh network
Net {
#[clap(subcommand)]
command: NodeCommands,
command: NetCommands,
},
/// Manage gossip
///
Expand All @@ -71,17 +71,55 @@ pub enum RpcCommands {
#[clap(subcommand)]
command: TagCommands,
},

/// Get statistics and metrics from the running node.
Stats,
/// Get status of the running node.
Status,
/// Shutdown the running node.
Shutdown {
/// Shutdown mode.
///
/// Hard shutdown will immediately terminate the process, soft shutdown will wait
/// for all connections to close.
#[clap(long, default_value_t = false)]
force: bool,
},
}

impl RpcCommands {
pub async fn run(self, iroh: &Iroh, env: &ConsoleEnv) -> Result<()> {
match self {
Self::Node { command } => command.run(iroh).await,
Self::Net { command } => command.run(iroh).await,
Self::Blobs { command } => command.run(iroh).await,
Self::Docs { command } => command.run(iroh, env).await,
Self::Authors { command } => command.run(iroh, env).await,
Self::Tags { command } => command.run(iroh).await,
Self::Gossip { command } => command.run(iroh).await,
Self::Stats => {
let stats = iroh.stats().await?;
for (name, details) in stats.iter() {
println!(
"{:23} : {:>6} ({})",
name, details.value, details.description
);
}
Ok(())
}
Self::Shutdown { force } => {
iroh.shutdown(force).await?;
Ok(())
}
Self::Status => {
let response = iroh.status().await?;
println!("Listening addresses: {:#?}", response.listen_addrs);
println!("Node ID: {}", response.addr.node_id);
println!("Version: {}", response.version);
if let Some(addr) = response.rpc_addr {
println!("RPC Addr: {}", addr);
}
Ok(())
}
}
}
}
1 change: 1 addition & 0 deletions iroh-cli/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ fn cli_provide_addresses() -> Result<()> {
}

#[test]
#[ignore = "flaky"]
fn cli_rpc_lock_restart() -> Result<()> {
let dir = testdir!();
let iroh_data_dir = dir.join("data-dir");
Expand Down
2 changes: 1 addition & 1 deletion iroh/examples/collection-fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ async fn main() -> Result<()> {
println!("fetching hash: {}", ticket.hash());
println!("node id: {}", node.node_id());
println!("node listening addresses:");
let addrs = node.node_addr().await?;
let addrs = node.net().node_addr().await?;
for addr in addrs.direct_addresses() {
println!("\t{:?}", addr);
}
Expand Down
2 changes: 1 addition & 1 deletion iroh/examples/hello-world-fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ async fn main() -> Result<()> {
println!("fetching hash: {}", ticket.hash());
println!("node id: {}", node.node_id());
println!("node listening addresses:");
let addrs = node.node_addr().await?;
let addrs = node.net().node_addr().await?;
for addr in addrs.direct_addresses() {
println!("\t{:?}", addr);
}
Expand Down
4 changes: 2 additions & 2 deletions iroh/examples/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//! $ cargo run --features=examples --example rpc
//! Then in another terminal, run any of the normal iroh CLI commands, which you can run from
//! cargo as well:
//! $ cargo run node stats
//! The `node stats` command will reach out over RPC to the node constructed in the example
//! $ cargo run net stats
//! The `net stats` command will reach out over RPC to the node constructed in the example
use clap::Parser;
use iroh_blobs::store::Store;
Expand Down
46 changes: 31 additions & 15 deletions iroh/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,28 @@
//!
//! See the documentation for [`Iroh`] for more information.
use std::collections::BTreeMap;

use anyhow::Result;
use futures_lite::{Stream, StreamExt};
use ref_cast::RefCast;
use std::ops::Deref;

use crate::rpc_protocol::node::{CounterStats, ShutdownRequest, StatsRequest, StatusRequest};
#[doc(inline)]
pub use crate::rpc_protocol::RpcService;

mod quic;

pub use self::docs::Doc;
pub use self::node::NodeStatus;
pub use self::net::NodeStatus;

pub(crate) use self::quic::{connect_raw as quic_connect_raw, RPC_ALPN};

pub mod authors;
pub mod blobs;
pub mod docs;
pub mod gossip;
pub mod node;
pub mod net;
pub mod tags;

/// Iroh rpc connection - boxed so that we can have a concrete type.
Expand Down Expand Up @@ -48,14 +51,6 @@ pub struct Iroh {
rpc: RpcClient,
}

impl Deref for Iroh {
type Target = node::Client;

fn deref(&self) -> &Self::Target {
self.node()
}
}

impl Iroh {
/// Creates a new high-level client to a Iroh node from the low-level RPC client.
///
Expand Down Expand Up @@ -92,15 +87,36 @@ impl Iroh {
gossip::Client::ref_cast(&self.rpc)
}

/// Returns the node client.
pub fn node(&self) -> &node::Client {
node::Client::ref_cast(&self.rpc)
/// Returns the net client.
pub fn net(&self) -> &net::Client {
net::Client::ref_cast(&self.rpc)
}

/// Shuts down the node.
///
/// If `force` is true, the node will be shut down instantly without
/// waiting for things to stop gracefully.
pub async fn shutdown(&self, force: bool) -> Result<()> {
self.rpc.rpc(ShutdownRequest { force }).await?;
Ok(())
}

/// Fetches statistics of the running node.
pub async fn stats(&self) -> Result<BTreeMap<String, CounterStats>> {
let res = self.rpc.rpc(StatsRequest {}).await??;
Ok(res.stats)
}

/// Fetches status information about this node.
pub async fn status(&self) -> Result<NodeStatus> {
let response = self.rpc.rpc(StatusRequest).await??;
Ok(response)
}
}

fn flatten<T, E1, E2>(
s: impl Stream<Item = Result<Result<T, E1>, E2>>,
) -> impl Stream<Item = anyhow::Result<T>>
) -> impl Stream<Item = Result<T>>
where
E1: std::error::Error + Send + Sync + 'static,
E2: std::error::Error + Send + Sync + 'static,
Expand Down
2 changes: 1 addition & 1 deletion iroh/src/client/blobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1321,7 +1321,7 @@ mod tests {
let import_outcome = node1.blobs().add_bytes(&b"hello world"[..]).await?;

// Download in node2
let node1_addr = node1.node_addr().await?;
let node1_addr = node1.net().node_addr().await?;
let res = node2
.blobs()
.download(import_outcome.hash, node1_addr)
Expand Down
Loading

0 comments on commit 6354e04

Please sign in to comment.