From 8810d55d7515d49a6b5fa21e02cf5b254f7e877a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cramfox=E2=80=9D?= <“kasey@n0.computer”> Date: Fri, 6 Dec 2024 15:05:17 -0500 Subject: [PATCH 1/3] docs: add `INSTALL.md` with "getting started" instructions --- INSTALL.md | 41 +++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 2 files changed, 42 insertions(+) create mode 100644 INSTALL.md diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 000000000..5c408c13a --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,41 @@ +# Getting started + +The `iroh-blobs` protocol is meant to be use in conjunction with `iroh`. [Iroh](https://docs.rs/iroh/latest/iroh/index.html) is a networking library for making direct connections, these connections are what power the data transfers in `iroh-blobs`. + +Iroh provides a [`Router`](https://docs.rs/iroh/latest/iroh/protocol/struct.Router.html) that takes an [`Endpoint`](https://docs.rs/iroh/latest/iroh/endpoint/struct.Endpoint.html) and any protocols needed for the application. Similar to a router in webserver library, it runs a loop accepting incoming connections and routes them to the specific protocol handler, based on `ALPN`. + +Here is a basic example of how to set up `iroh-blobs` with `iroh`: + +```rust +use iroh::{protocol::Router, Endpoint}; +use iroh_blobs::{net_protocol::Blobs, util::local_pool::LocalPool}; + +#[tokio::main] +async fn main() -> Result<(), std::fmt::Error> { + // create an iroh endpoint that includes the standard discovery mechanisms + // we've built at number0 + let endpoint = Endpoint::builder().discovery_n0().bind().await.unwrap(); + + // spawn a local pool with one thread per CPU + // for a single threaded pool use `LocalPool::single` + let local_pool = LocalPool::default(); + + // create an in-memory blob store + // use `iroh_blobs::net_protocol::Blobs::persistent` to load or create a + // persistent blob store from a path + let blobs = Blobs::memory().build(local_pool.handle(), &endpoint); + + // turn on the "rpc" feature if you need to create blobs and tags clients + let blobs_client = blobs.clone().client(); + let tags_client = blobs_client.tags(); + + // build the router + let router = Router::builder(endpoint) + .accept(iroh_blobs::ALPN, blobs) + .spawn(); + + // do fun stuff with the blobs protocol! + // make sure not to drop the local_pool before you are finished + Ok(()) +} +``` diff --git a/src/lib.rs b/src/lib.rs index 6c3063a1a..c4537b281 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,6 +23,7 @@ //! //! [BLAKE3]: https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf //! [iroh]: https://docs.rs/iroh +#![doc = include_str!("../INSTALL.md")] #![deny(missing_docs, rustdoc::broken_intra_doc_links)] #![recursion_limit = "256"] #![cfg_attr(iroh_docsrs, feature(doc_cfg))] From 7643ec90bbc579d6162dce80eaf975664d21d375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cramfox=E2=80=9D?= <“kasey@n0.computer”> Date: Fri, 6 Dec 2024 16:37:00 -0500 Subject: [PATCH 2/3] remove INSTALL.md, move content to README.md --- INSTALL.md | 41 ----------------------------------------- README.md | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 2 +- 3 files changed, 45 insertions(+), 43 deletions(-) delete mode 100644 INSTALL.md diff --git a/INSTALL.md b/INSTALL.md deleted file mode 100644 index 5c408c13a..000000000 --- a/INSTALL.md +++ /dev/null @@ -1,41 +0,0 @@ -# Getting started - -The `iroh-blobs` protocol is meant to be use in conjunction with `iroh`. [Iroh](https://docs.rs/iroh/latest/iroh/index.html) is a networking library for making direct connections, these connections are what power the data transfers in `iroh-blobs`. - -Iroh provides a [`Router`](https://docs.rs/iroh/latest/iroh/protocol/struct.Router.html) that takes an [`Endpoint`](https://docs.rs/iroh/latest/iroh/endpoint/struct.Endpoint.html) and any protocols needed for the application. Similar to a router in webserver library, it runs a loop accepting incoming connections and routes them to the specific protocol handler, based on `ALPN`. - -Here is a basic example of how to set up `iroh-blobs` with `iroh`: - -```rust -use iroh::{protocol::Router, Endpoint}; -use iroh_blobs::{net_protocol::Blobs, util::local_pool::LocalPool}; - -#[tokio::main] -async fn main() -> Result<(), std::fmt::Error> { - // create an iroh endpoint that includes the standard discovery mechanisms - // we've built at number0 - let endpoint = Endpoint::builder().discovery_n0().bind().await.unwrap(); - - // spawn a local pool with one thread per CPU - // for a single threaded pool use `LocalPool::single` - let local_pool = LocalPool::default(); - - // create an in-memory blob store - // use `iroh_blobs::net_protocol::Blobs::persistent` to load or create a - // persistent blob store from a path - let blobs = Blobs::memory().build(local_pool.handle(), &endpoint); - - // turn on the "rpc" feature if you need to create blobs and tags clients - let blobs_client = blobs.clone().client(); - let tags_client = blobs_client.tags(); - - // build the router - let router = Router::builder(endpoint) - .accept(iroh_blobs::ALPN, blobs) - .spawn(); - - // do fun stuff with the blobs protocol! - // make sure not to drop the local_pool before you are finished - Ok(()) -} -``` diff --git a/README.md b/README.md index b6e99e47e..9f9909c0f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ request blobs or ranges of blobs, as well as collections. The requester opens a quic stream to the provider and sends the request. The provider answers with the requested data, encoded as [blake3](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf) verified streams, on the same quic stream. -This crate is usually used together with [iroh-net](https://crates.io/crates/iroh-net), but can also be used with normal [quinn](https://crates.io/crates/quinn) connections. Connection establishment is left up to the user or a higher level APIs such as the iroh CLI. +This crate is usually used together with [iroh](https://crates.io/crates/iroh), but can also be used with normal [quinn](https://crates.io/crates/quinn) connections. Connection establishment is left up to the user or a higher level APIs such as the iroh CLI. ## Concepts @@ -21,6 +21,49 @@ This crate is usually used together with [iroh-net](https://crates.io/crates/iro - **Requester:** The side that asks for data. It is initiating requests to one or many providers. + +## Getting started + +The `iroh-blobs` protocol was designed to be used in conjunction with `iroh`. [Iroh](https://docs.rs/iroh) is a networking library for making direct connections, these connections are what power the data transfers in `iroh-blobs`. + +Iroh provides a [`Router`](https://docs.rs/iroh/latest/iroh/protocol/struct.Router.html) that takes an [`Endpoint`](https://docs.rs/iroh/latest/iroh/endpoint/struct.Endpoint.html) and any protocols needed for the application. Similar to a router in webserver library, it runs a loop accepting incoming connections and routes them to the specific protocol handler, based on `ALPN`. + +Here is a basic example of how to set up `iroh-blobs` with `iroh`: + +```rust +use iroh::{protocol::Router, Endpoint}; +use iroh_blobs::{net_protocol::Blobs, util::local_pool::LocalPool}; + +#[tokio::main] +async fn main() -> Result<(), std::fmt::Error> { + // create an iroh endpoint that includes the standard discovery mechanisms + // we've built at number0 + let endpoint = Endpoint::builder().discovery_n0().bind().await.unwrap(); + + // spawn a local pool with one thread per CPU + // for a single threaded pool use `LocalPool::single` + let local_pool = LocalPool::default(); + + // create an in-memory blob store + // use `iroh_blobs::net_protocol::Blobs::persistent` to load or create a + // persistent blob store from a path + let blobs = Blobs::memory().build(local_pool.handle(), &endpoint); + + // turn on the "rpc" feature if you need to create blobs and tags clients + let blobs_client = blobs.client(); + let tags_client = blobs_client.tags(); + + // build the router + let router = Router::builder(endpoint) + .accept(iroh_blobs::ALPN, blobs.clone()) + .spawn(); + + // do fun stuff with the blobs protocol! + // make sure not to drop the local_pool before you are finished + Ok(()) +} +``` + ## Examples Examples that use `iroh-blobs` can be found in the `iroh` crate. the iroh crate publishes `iroh_blobs` as `iroh::bytes`. diff --git a/src/lib.rs b/src/lib.rs index c4537b281..9404e40c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +#![doc = include_str!("../README.md")] //! Blobs layer for iroh. //! //! The crate is designed to be used from the [iroh] crate, which provides a @@ -23,7 +24,6 @@ //! //! [BLAKE3]: https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf //! [iroh]: https://docs.rs/iroh -#![doc = include_str!("../INSTALL.md")] #![deny(missing_docs, rustdoc::broken_intra_doc_links)] #![recursion_limit = "256"] #![cfg_attr(iroh_docsrs, feature(doc_cfg))] From b667224c3d1d82976747edda9fff159695fd4d9b Mon Sep 17 00:00:00 2001 From: Ruediger Klaehn Date: Wed, 11 Dec 2024 12:17:07 +0200 Subject: [PATCH 3/3] add example from readme as separate example --- Cargo.toml | 4 ++++ README.md | 10 +++++++--- examples/setup.rs | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 examples/setup.rs diff --git a/Cargo.toml b/Cargo.toml index d92f1e042..35d948efa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -154,6 +154,10 @@ required-features = ["example-iroh"] name = "custom-protocol" required-features = ["example-iroh"] +[[example]] +name = "setup" +required-features = ["example-iroh"] + [lints.rust] missing_debug_implementations = "warn" diff --git a/README.md b/README.md index 9f9909c0f..3ca254bdb 100644 --- a/README.md +++ b/README.md @@ -35,10 +35,10 @@ use iroh::{protocol::Router, Endpoint}; use iroh_blobs::{net_protocol::Blobs, util::local_pool::LocalPool}; #[tokio::main] -async fn main() -> Result<(), std::fmt::Error> { +async fn main() -> anyhow::Result<()> { // create an iroh endpoint that includes the standard discovery mechanisms // we've built at number0 - let endpoint = Endpoint::builder().discovery_n0().bind().await.unwrap(); + let endpoint = Endpoint::builder().discovery_n0().bind().await?; // spawn a local pool with one thread per CPU // for a single threaded pool use `LocalPool::single` @@ -56,10 +56,14 @@ async fn main() -> Result<(), std::fmt::Error> { // build the router let router = Router::builder(endpoint) .accept(iroh_blobs::ALPN, blobs.clone()) - .spawn(); + .spawn() + .await?; // do fun stuff with the blobs protocol! // make sure not to drop the local_pool before you are finished + router.shutdown().await?; + drop(local_pool); + drop(tags_client); Ok(()) } ``` diff --git a/examples/setup.rs b/examples/setup.rs new file mode 100644 index 000000000..c8b93330a --- /dev/null +++ b/examples/setup.rs @@ -0,0 +1,35 @@ +use iroh::{protocol::Router, Endpoint}; +use iroh_blobs::{net_protocol::Blobs, util::local_pool::LocalPool}; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // create an iroh endpoint that includes the standard discovery mechanisms + // we've built at number0 + let endpoint = Endpoint::builder().discovery_n0().bind().await?; + + // spawn a local pool with one thread per CPU + // for a single threaded pool use `LocalPool::single` + let local_pool = LocalPool::default(); + + // create an in-memory blob store + // use `iroh_blobs::net_protocol::Blobs::persistent` to load or create a + // persistent blob store from a path + let blobs = Blobs::memory().build(local_pool.handle(), &endpoint); + + // turn on the "rpc" feature if you need to create blobs and tags clients + let blobs_client = blobs.client(); + let tags_client = blobs_client.tags(); + + // build the router + let router = Router::builder(endpoint) + .accept(iroh_blobs::ALPN, blobs.clone()) + .spawn() + .await?; + + // do fun stuff with the blobs protocol! + // make sure not to drop the local_pool before you are finished + router.shutdown().await?; + drop(local_pool); + drop(tags_client); + Ok(()) +}