Skip to content

Instantly share code, notes, and snippets.

@hyone
Last active July 11, 2017 01:07
Show Gist options
  • Save hyone/e5d1bbb905c31c9f7c40e65593da2905 to your computer and use it in GitHub Desktop.
Save hyone/e5d1bbb905c31c9f7c40e65593da2905 to your computer and use it in GitHub Desktop.
Rust で並列HTTP Request ref: http://qiita.com/hyone/items/32698ae6e3de641a0fa1
[package]
name = "http_request1"
version = "0.1.0"
[dependencies]
hyper = "*"
extern crate hyper;
use std::io::prelude::*;
use std::io::stderr;
use std::sync::Arc;
use std::thread;
use std::time::{ Duration, SystemTime };
use hyper::Client;
fn to_seconds(duration: &Duration) -> f64 {
let nanos = duration.subsec_nanos() as u64;
let secs = duration.as_secs();
((1000_000_000 * secs + nanos) as f64) / 1000_000_000.
}
fn do_http_request(client: Arc<Client>, index: usize, url: &str) {
let time = SystemTime::now();
let result = client.get(url).send();
let duration = to_seconds(&time.elapsed().unwrap());
match result {
Ok(response) => {
println!("{:2}: {:5.3}: {} => {}",
index, duration, url, response.status);
}
Err(e) => {
let _ = writeln!(&mut stderr(), "{:2}: Error: {}", index, e);
}
};
}
fn main() {
let gen_url = |q: &str| -> String { format!("http://www.google.com/search?q={}", q) };
let urls: Vec<String> =
vec!["clojure", "haskell", "ocaml", "rust", "scala"]
.iter().map(|q| gen_url(q))
.chain(vec!["http://127.0.0.1:5000/".to_owned()].into_iter())
.chain(vec!["javascript", "python", "perl", "php", "ruby"]
.iter().map(|q| gen_url(q)))
.collect();
let client = Arc::new(Client::new());
let mut children = vec![];
for (i, url) in urls.into_iter().enumerate() {
let client = client.clone();
children.push(thread::spawn(move || {
do_http_request(client, i+1, &url)
}));
}
for child in children {
let _ = child.join();
}
}
// To check parallel http requests, prepare a long time request:
// $ rackup -s webrick --port 5000 -b 'run(proc { |env| sleep 5; ["200", {"Content-Type" => "text/html"}, ["Hello World"]] })'
// $ cargo run
// ...
// 1: 0.221: http://www.google.com/search?q=clojure => 200 OK
// 9: 0.223: http://www.google.com/search?q=perl => 200 OK
// 8: 0.223: http://www.google.com/search?q=python => 200 OK
// 10: 0.229: http://www.google.com/search?q=php => 200 OK
// 7: 0.235: http://www.google.com/search?q=javascript => 200 OK
// 5: 0.287: http://www.google.com/search?q=scala => 200 OK
// 11: 0.294: http://www.google.com/search?q=ruby => 200 OK
// 3: 0.303: http://www.google.com/search?q=ocaml => 200 OK
// 2: 0.429: http://www.google.com/search?q=haskell => 200 OK
// 4: 0.550: http://www.google.com/search?q=rust => 200 OK
// 6: 5.005: http://127.0.0.1:5000/ => 200 OK
let children = urls.into_iter().enumerate().map(|(i, url)| {
let client = client.clone();
thread::spawn(move || do_http_request(client, i+1, &url))
});
$ cargo run
...
1: 0.708: http://www.google.com/search?q=clojure => 200 OK
2: 0.186: http://www.google.com/search?q=haskell => 200 OK
3: 0.179: http://www.google.com/search?q=ocaml => 200 OK
4: 0.508: http://www.google.com/search?q=rust => 200 OK
5: 0.179: http://www.google.com/search?q=scala => 200 OK
6: 5.045: http://127.0.0.1:5000/ => 200 OK
7: 0.173: http://www.google.com/search?q=javascript => 200 OK
8: 0.181: http://www.google.com/search?q=python => 200 OK
9: 0.177: http://www.google.com/search?q=perl => 200 OK
10: 0.192: http://www.google.com/search?q=php => 200 OK
11: 0.202: http://www.google.com/search?q=ruby => 200 OK
extern crate hyper;
use std::io::prelude::*;
use std::io::stderr;
use std::sync::Arc;
use std::thread;
use std::time::{ Duration, SystemTime };
use hyper::Client;
fn to_seconds(duration: &Duration) -> f64 {
let nanos = duration.subsec_nanos() as u64;
let secs = duration.as_secs();
((1000_000_000 * secs + nanos) as f64) / 1000_000_000.
}
fn do_http_request(client: Arc<Client>, index: usize, url: &str) {
let time = SystemTime::now();
let result = client.get(url).send();
let duration = to_seconds(&time.elapsed().unwrap());
match result {
Ok(response) => {
println!("{:2}: {:5.3}: {} => {}",
index, duration, url, response.status);
}
Err(e) => {
let _ = writeln!(&mut stderr(), "{:2}: Error: {}", index, e);
}
};
}
fn main() {
let gen_url = |q: &str| -> String { format!("http://www.google.com/search?q={}", q) };
let urls: Vec<String> =
vec![].into_iter()
.chain(vec!["clojure", "haskell", "ocaml", "rust", "scala"]
.iter().map(|q| gen_url(q)))
.chain(vec!["http://127.0.0.1:5000/".to_owned()].into_iter())
.chain(vec!["javascript", "python", "perl", "php", "ruby"]
.iter().map(|q| gen_url(q)))
.collect();
let client = Arc::new(Client::new());
let children = urls.into_iter().enumerate().map(|(i, url)| {
let client = client.clone();
thread::spawn(move || do_http_request(client, i+1, &url))
}).collect::<Vec<_>>();
for child in children {
let _ = child.join();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment