Add nicer doctest; revert smoke-test.
This commit is contained in:
committed by
Martin Algesten
parent
5a55f94101
commit
64ebd47979
@@ -1,11 +1,11 @@
|
|||||||
use std::io::{self, BufRead, BufReader, Read, Write};
|
use std::io::{self, BufRead, BufReader, Read};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread::{self, JoinHandle};
|
use std::thread::{self, JoinHandle};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{env, error, fmt, result, result::Result};
|
use std::{env, error, fmt, result};
|
||||||
|
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use ureq::{self, Response};
|
use ureq;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Oops(String);
|
struct Oops(String);
|
||||||
@@ -30,13 +30,14 @@ impl fmt::Display for Oops {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(agent: &ureq::Agent, url: &str) -> std::result::Result<(), Oops> {
|
type Result<T> = result::Result<T, Oops>;
|
||||||
let r = get_response(agent, url)?;
|
|
||||||
let mut reader = r.into_reader();
|
fn get(agent: &ureq::Agent, url: &str) -> Result<Vec<u8>> {
|
||||||
|
let response = agent.get(url).call()?;
|
||||||
|
let mut reader = response.into_reader();
|
||||||
let mut bytes = vec![];
|
let mut bytes = vec![];
|
||||||
reader.read_to_end(&mut bytes)?;
|
reader.read_to_end(&mut bytes)?;
|
||||||
std::io::stdout().write_all(&bytes)?;
|
Ok(bytes)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_and_write(agent: &ureq::Agent, url: &str) {
|
fn get_and_write(agent: &ureq::Agent, url: &str) {
|
||||||
@@ -47,26 +48,7 @@ fn get_and_write(agent: &ureq::Agent, url: &str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use ureq::Error::{Status, Transport};
|
fn get_many(urls: Vec<String>, simultaneous_fetches: usize) -> Result<()> {
|
||||||
|
|
||||||
fn get_response(agent: &ureq::Agent, url: &str) -> result::Result<Response, ureq::Error> {
|
|
||||||
let fetch = || agent.get(url).call();
|
|
||||||
for _ in 1..4 {
|
|
||||||
match fetch() {
|
|
||||||
Err(Status(429, r)) => {
|
|
||||||
let retry: Option<u64> = r.header("retry-after").and_then(|h| h.parse().ok());
|
|
||||||
eprintln!("429 for {}, retrying in {}", r.status(), r.get_url());
|
|
||||||
thread::sleep(Duration::from_secs(retry.unwrap_or(5)));
|
|
||||||
eprintln!("error status {} body {}", r.status(), r.into_string()?);
|
|
||||||
}
|
|
||||||
result => return result,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// Last try, return success or failure regardless of status code.
|
|
||||||
fetch()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_many(urls: Vec<String>, simultaneous_fetches: usize) -> Result<(), Oops> {
|
|
||||||
let agent = ureq::builder()
|
let agent = ureq::builder()
|
||||||
.timeout_connect(Duration::from_secs(5))
|
.timeout_connect(Duration::from_secs(5))
|
||||||
.timeout(Duration::from_secs(20))
|
.timeout(Duration::from_secs(20))
|
||||||
@@ -94,7 +76,7 @@ fn get_many(urls: Vec<String>, simultaneous_fetches: usize) -> Result<(), Oops>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Oops> {
|
fn main() -> Result<()> {
|
||||||
let args = env::args();
|
let args = env::args();
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
println!(
|
println!(
|
||||||
|
|||||||
38
src/error.rs
38
src/error.rs
@@ -18,29 +18,25 @@ use crate::Response;
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::{result::Result, time::Duration, thread};
|
/// use std::{result::Result, time::Duration, thread};
|
||||||
/// use ureq::{Response, Error};
|
/// use ureq::{Response, Error, Error::Status};
|
||||||
/// # fn main(){ ureq::is_test(true); get_response(); }
|
/// # fn main(){ ureq::is_test(true); get_response( "http://httpbin.org/status/500" ); }
|
||||||
///
|
///
|
||||||
/// // An example of a function that handles HTTP 500 errors differently
|
/// // An example of a function that handles HTTP 429 and 500 errors differently
|
||||||
/// // than other errors.
|
/// // than other errors. They get retried after a suitable delay, up to 4 times.
|
||||||
/// fn get_response() -> Result<Response, Error> {
|
/// fn get_response(url: &str) -> Result<Response, Error> {
|
||||||
/// let fetch = || ureq::get("http://httpbin.org/status/500").call();
|
/// for _ in 1..4 {
|
||||||
/// let mut result = fetch();
|
/// match ureq::get(url).call() {
|
||||||
/// for _ in 1..4 {
|
/// Err(Status(503, r)) | Err(Status(429, r)) => {
|
||||||
/// let err: ureq::Error = match result {
|
/// let retry: Option<u64> = r.header("retry-after").and_then(|h| h.parse().ok());
|
||||||
/// Ok(r) => return Ok(r),
|
/// let retry = retry.unwrap_or(5);
|
||||||
/// Err(e) => e,
|
/// eprintln!("{} for {}, retry in {}", r.status(), r.get_url(), retry);
|
||||||
/// };
|
/// thread::sleep(Duration::from_secs(retry));
|
||||||
/// match err {
|
/// }
|
||||||
/// // Retry 500s after waiting for two seconds.
|
/// result => return result,
|
||||||
/// Error::Status(500, _) => thread::sleep(Duration::from_secs(2)),
|
/// };
|
||||||
/// Error::Status(_, r) => return Err(r.into()),
|
|
||||||
/// Error::Transport(e) => return Err(e.into()),
|
|
||||||
/// }
|
/// }
|
||||||
/// result = fetch();
|
/// // Ran out of retries; try one last time and return whatever result we get.
|
||||||
/// }
|
/// ureq::get(url).call()
|
||||||
/// println!("Failed after 5 tries: {:?}", &result);
|
|
||||||
/// result
|
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
Reference in New Issue
Block a user