Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions iroh-services/access.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,23 @@ The environment variable used by the Rust client is `IROH_SERVICES_API_SECRET` (

## Use it in your app

Pass the key when building your `iroh_services::Client`:
Pass the key to `iroh_services::preset()`, bind your endpoint with the preset,
then hand the same preset to the client:

```rust
use iroh_services::Client;
use iroh::Endpoint;

let client = Client::builder(&endpoint)
let preset = iroh_services::preset()
.api_secret_from_str("YOUR_API_KEY")?
.build()
.await?;
.build()?;

let endpoint = Endpoint::bind(preset.clone()).await?;

let client = preset.client_builder(&endpoint).build().await?;
```

The preset carries the key, so you don't pass it to the client a second time.

In production, load the key from a config file or environment variable instead
of hardcoding it.

Expand Down
49 changes: 39 additions & 10 deletions iroh-services/metrics/custom.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,52 @@ successfully, we will report the metric to the Iroh Services platform.

For a complete example, see the [iroh-ping example on GitHub](https://github.com/n0-computer/iroh-ping).

Custom metrics live in a struct that derives `MetricsGroup` from the
`iroh-metrics` crate, which you register on the client:

```bash
cargo add iroh-metrics
```

```rust
use iroh::{Endpoint, endpoint::presets};
use iroh_services::Client;
use std::sync::Arc;

use iroh::Endpoint;
use iroh_metrics::{Counter, MetricsGroup};

/// Metrics for our docs protocol.
#[derive(Debug, Default, MetricsGroup)]
#[metrics(name = "docs")]
struct DocsMetrics {
/// Documents written successfully
documents_written: Counter,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let endpoint = Endpoint::bind(presets::N0).await?;
endpoint.online().await;

let client = Client::builder(&endpoint)
let preset = iroh_services::preset()
.api_secret_from_str("YOUR_API_KEY")?
.build()?;

let endpoint = Endpoint::bind(preset.clone()).await?;
endpoint.online().await;

// Register the group with the client. It ships alongside the built-in
// endpoint metrics on the client's reporting interval.
let metrics = Arc::new(DocsMetrics::default());
let client = preset
.client_builder(&endpoint)
.register_metrics_group(metrics.clone())
.build()
.await?;
// Report a custom metric
client.metric("document_written", 1).await?;

// Each time a document is written, bump the counter
metrics.documents_written.inc();

Ok(())
}
```

The doc comment on each field becomes its help text, and `#[metrics(name = ...)]`
names the group. Call `client.push_metrics()` if you need a dump sent
immediately rather than waiting for the next interval.
34 changes: 20 additions & 14 deletions iroh-services/net-diagnostics/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -73,30 +73,36 @@ cargo add iroh-services

Build an `iroh_services::Client`, grant iroh services the
`NetDiagnosticsCap::GetAny` capability so it can request diagnostics, and run a
`ClientHost` so it can dial back into your endpoint. The client reads the API
key you exported in step 1:
`ClientHost` so it can dial back into your endpoint.

At startup, build a preset from the API key you exported in step 1 and bind your
endpoint with it:

```rust
let preset = iroh_services::preset().api_secret_from_env()?.build()?;
let endpoint = Endpoint::bind(preset.clone()).await?;
```

Then pass that preset alongside the endpoint. Its `client_builder` hands the API
key to the client, so you don't supply it twice:

```rust
use anyhow::Result;
use iroh::{Endpoint, protocol::Router};
use iroh_services::{
ApiSecret, Client, ClientHost, CLIENT_HOST_ALPN, API_SECRET_ENV_VAR_NAME,
caps::NetDiagnosticsCap,
ClientHost, CLIENT_HOST_ALPN, IrohServicesPreset, caps::NetDiagnosticsCap,
};

async fn setup_net_diagnostics(endpoint: &Endpoint) -> Result<Router> {
// Get your secret somehow, either from an environment variable or config file
let secret = ApiSecret::from_env_var(API_SECRET_ENV_VAR_NAME)?;

async fn setup_net_diagnostics(
preset: &IrohServicesPreset,
endpoint: &Endpoint,
) -> Result<Router> {
// The remote_id is the id of the endpoint we'll be sending the network
// report to, derived from the secret's address
let remote_id = secret.addr().id;
// report to, derived from the API key's address
let remote_id = preset.api_secret().addr().id;

// Build the client
let client = Client::builder(endpoint)
.api_secret(secret)?
.build()
.await?;
let client = preset.client_builder(endpoint).build().await?;

// Grant the GetAny capability so the platform can request diagnostics
// from this endpoint on demand
Expand Down
20 changes: 13 additions & 7 deletions snippets/iroh-services-setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,26 @@ Then, in your code, create a client and connect your endpoint to Iroh Services.
<CodeGroup>

```rust Rust
use iroh::{Endpoint, endpoint::presets};
use iroh_services::Client;
use iroh::Endpoint;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Create an iroh endpoint
let endpoint = Endpoint::bind(presets::N0).await?;
// Build a preset from your API key. In production, load the key from a
// config file or environment variable instead of hardcoding it.
let preset = iroh_services::preset()
.api_secret_from_str("YOUR_API_KEY")?
.build()?;

// Create an iroh endpoint with the preset
let endpoint = Endpoint::bind(preset.clone()).await?;

// Wait for the endpoint to be online
endpoint.online().await;

// Create the Iroh Services client with your API key.
let client = Client::builder(&endpoint)
.api_secret_from_str("YOUR_API_KEY")?
// Create the Iroh Services client. `client_builder` reuses the preset's
// API key, which also carries the address of the service to dial.
let client = preset
.client_builder(&endpoint)
.name("my-endpoint")?
.build()
.await?;
Expand Down
Loading