Skip to content

Instantly share code, notes, and snippets.

@mrnugget
Created October 21, 2024 19:15
Show Gist options
  • Save mrnugget/571dd2560b910f33385fea99084576ea to your computer and use it in GitHub Desktop.
Save mrnugget/571dd2560b910f33385fea99084576ea to your computer and use it in GitHub Desktop.
use anyhow::Result;
use std::convert::Infallible;
use warp::Filter;
struct Deferred<T: FnOnce()> {
task: Option<T>,
}
impl<T: FnOnce()> Deferred<T> {
fn abort(&mut self) {
self.task.take();
}
}
impl<T: FnOnce()> Drop for Deferred<T> {
fn drop(&mut self) {
if let Some(task) = self.task.take() {
task();
}
}
}
fn defer<T: FnOnce()>(f: T) -> Deferred<T> {
Deferred { task: Some(f) }
}
async fn send_request(url: &str, metrics: &mut Metrics) -> Result<String> {
let mut finish = defer(|| metrics.requests += 1);
let request = reqwest::get(url);
tokio::select! {
response = request => {
let response = response?;
let body = response.text().await?;
Ok(body)
}
_ = tokio::time::sleep(std::time::Duration::from_millis(2500)) => {
finish.abort();
Err(anyhow::anyhow!("timeout"))
}
}
}
struct Metrics {
requests: usize,
}
#[tokio::main]
async fn main() {
let routes = warp::path::param().and_then(sleepy);
tokio::spawn(warp::serve(routes).run(([127, 0, 0, 1], 3030)));
let mut metrics = Metrics { requests: 0 };
for (i, sleep) in (1..5).into_iter().enumerate() {
println!("Sending request #{i}. sleep={sleep}s");
let url = format!("http://127.0.0.1:3030/{sleep}");
let result = send_request(&url, &mut metrics).await;
println!("request #{i} result = {result:?}");
println!("metrics.requests = {}", metrics.requests);
println!("-----------");
}
}
async fn sleepy(Seconds(seconds): Seconds) -> Result<impl warp::Reply, Infallible> {
tokio::time::sleep(std::time::Duration::from_secs(seconds)).await;
Ok(format!("I waited {} seconds!", seconds))
}
struct Seconds(u64);
impl std::str::FromStr for Seconds {
type Err = ();
fn from_str(src: &str) -> Result<Self, Self::Err> {
src.parse::<u64>().map_err(|_| ()).map(Seconds)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment