Skip to content

Commit

Permalink
refactor: Upgrade to hyper 1.0 (#1858)
Browse files Browse the repository at this point in the history
## Description

This upgrades our direct use of hyper to version 1.0 of the crate.

## Notes & open questions

This is adds a little duplication to our deps for now since reqwest is
still
using hyper 1.0.

## Change checklist

- [x] Self-review.
- [x] Documentation updates if relevant.
- [x] Tests if relevant.
  • Loading branch information
flub committed Dec 5, 2023
1 parent b95eb86 commit b8aa5d6
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 293 deletions.
128 changes: 103 additions & 25 deletions Cargo.lock

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

12 changes: 8 additions & 4 deletions iroh-metrics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ rust-version = "1.72"
workspace = true

[dependencies]
prometheus-client = { version = "0.22.0", optional = true }
once_cell = "1.17.0"
tracing = "0.1"
hyper = { version = "0.14.25", features = ["server", "client", "http1", "tcp"] }
anyhow = "1.0.75"
erased_set = "0.7"
http-body-util = "0.1.0"
hyper = { version = "1", features = ["server", "http1"] }
hyper-util = { version = "0.1.1", features = ["tokio"] }
once_cell = "1.17.0"
prometheus-client = { version = "0.22.0", optional = true }
struct_iterable = "0.1"
tokio = { version = "1", features = ["rt", "net"]}
tracing = "0.1"

[dev-dependencies]
tokio = { version = "1", features = ["io-util", "sync", "rt", "net", "fs", "macros", "time", "test-util"] }
Expand Down
5 changes: 2 additions & 3 deletions iroh-metrics/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,12 @@
//! inc!(Metrics, things_added);
//! ```

#[cfg(feature = "metrics")]
use hyper::Error;
// TODO: move cfg to lib.rs
#[cfg(feature = "metrics")]
use std::net::SocketAddr;

/// Start a server to serve the OpenMetrics endpoint.
#[cfg(feature = "metrics")]
pub async fn start_metrics_server(addr: SocketAddr) -> Result<(), Error> {
pub async fn start_metrics_server(addr: SocketAddr) -> anyhow::Result<()> {
crate::service::run(addr).await
}
70 changes: 36 additions & 34 deletions iroh-metrics/src/service.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,45 @@
use std::{future::Future, io, net::SocketAddr, pin::Pin};
use std::net::SocketAddr;

use hyper::{
service::{make_service_fn, service_fn},
Body, Error, Request, Response, Server,
};

use tracing::info;
use anyhow::{anyhow, Result};
use hyper::service::service_fn;
use hyper::{Request, Response};
use tokio::net::TcpListener;
use tracing::{error, info};

use crate::core::Core;

type BytesBody = http_body_util::Full<hyper::body::Bytes>;

/// Start a HTTP server to report metrics.
pub async fn run(metrics_addr: SocketAddr) -> Result<(), Error> {
pub async fn run(metrics_addr: SocketAddr) -> Result<()> {
info!("Starting metrics server on {metrics_addr}");
Server::bind(&metrics_addr)
.serve(make_service_fn(move |_conn| async move {
let handler = make_handler();
Ok::<_, io::Error>(service_fn(handler))
}))
.await
let listener = TcpListener::bind(metrics_addr).await?;
loop {
let (stream, _addr) = listener.accept().await?;
let io = hyper_util::rt::TokioIo::new(stream);
tokio::spawn(async move {
if let Err(err) = hyper::server::conn::http1::Builder::new()
.serve_connection(io, service_fn(handler))
.await
{
error!("Error serving metrics connection: {err:#}");
}
});
}
}

/// This function returns an HTTP handler fn that will respond with the
/// OpenMetrics encoding of our metrics.
fn make_handler(
) -> impl Fn(Request<Body>) -> Pin<Box<dyn Future<Output = io::Result<Response<Body>>> + Send>> {
// This closure accepts a request and responds with the OpenMetrics encoding of our metrics.
move |_req: Request<Body>| {
Box::pin(async move {
let core = Core::get()
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "metrics disabled"))?;
core.encode()
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
.map(|r| {
let body = Body::from(r);
Response::builder()
.header(hyper::header::CONTENT_TYPE, "text/plain; charset=utf-8")
.body(body)
.expect("Failed to build response")
})
})
}
/// HTTP handler that will respond with the OpenMetrics encoding of our metrics.
async fn handler(_req: Request<hyper::body::Incoming>) -> Result<Response<BytesBody>> {
let core = Core::get().ok_or_else(|| anyhow!("metrics disabled"))?;
core.encode().map_err(anyhow::Error::new).map(|r| {
Response::builder()
.header(hyper::header::CONTENT_TYPE, "text/plain; charset=utf-8")
.body(body_full(r))
.expect("Failed to build response")
})
}

/// Creates a new [`BytesBody`] with given content.
fn body_full(content: impl Into<hyper::body::Bytes>) -> BytesBody {
http_body_util::Full::new(content.into())
}
8 changes: 5 additions & 3 deletions iroh-net/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ ed25519-dalek = { version = "2.0.0", features = ["serde", "rand_core"] }
flume = "0.11"
futures = "0.3.25"
governor = "0.6.0"
iroh-base = { version = "0.11.0", path = "../iroh-base" }
hex = "0.4.3"
hostname = "0.3.1"
http = "0.2.9"
hyper = { version = "0.14.25", features = ["server", "client", "http1", "tcp"] }
http = "1"
http-body-util = "0.1.0"
hyper = { version = "1", features = ["server", "client", "http1"] }
hyper-util = "0.1.1"
igd = { version = "0.12.1", features = ["aio"] }
iroh-base = { version = "0.11.0", path = "../iroh-base" }
libc = "0.2.139"
num_enum = "0.7"
once_cell = "1.18.0"
Expand Down
Loading

0 comments on commit b8aa5d6

Please sign in to comment.