1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//! This example demonstrates how to customize the HTTP client. Standard pipeline and resilience
//! in particular.
use std::time::Duration;
use fetch::fake::{FakeDeps, FakeHandler};
use fetch::resilience::HttpClone;
use fetch::resilience::retry::HttpRetryLayerExt;
use fetch::{HttpClient, HttpResponse, HttpResponseBuilder, StatusExt};
use http::StatusCode;
#[path = "util/utils.rs"]
mod utils;
#[tokio::main]
async fn main() -> Result<(), ohno::AppError> {
utils::init_tracing();
// Simulate issues with the request by using a fake handler.
let fake_handler = FakeHandler::from_fn(|req| {
let status_code = match fastrand::u32(0..10) {
0..5 => StatusCode::INTERNAL_SERVER_ERROR,
_ => StatusCode::OK,
};
HttpResponseBuilder::new_fake()
.status(status_code)
.text(format!("response from {}", req.uri()))
.build()
});
let client = HttpClient::builder_fake(fake_handler, FakeDeps::default())
.standard_pipeline(|pipeline, _context| {
pipeline
// Increase the total timeout for the pipeline.
.total_timeout(|timeout| timeout.timeout(Duration::from_mins(1)))
// Customize the retry behavior.
.retry(|retry| {
retry
.base_delay(Duration::ZERO)
.max_retry_attempts(50) // we can do many retries, this does not do any external IO
.http_clone(HttpClone::all()) // we clone all idempotent requests (PUT, DELETE, etc)
.http_recovery(|response: &HttpResponse| response.recovery())
})
// Decrease the attempt timeout.
.attempt_timeout(|timeout| timeout.timeout(Duration::from_secs(2)))
// Optionally, we could also customize the attempt_intercept callback.
.attempt_intercept(|intercept| {
intercept.modify_input(|req| {
// You can inspect/modify the request here.
println!("attempting request to {}", req.uri());
req
})
})
})
.build();
let text = client.get("https://example.com").fetch_text_body().await?;
println!("response: {text}");
Ok(())
}