hyperium / hyper

An HTTP library for Rust
https://hyper.rs
MIT License
14.29k stars 1.57k forks source link

can't reuse client in mio branch. #783

Closed siddontang closed 8 years ago

siddontang commented 8 years ago

Hi

I try to reuse the client, so I change the example client.rs to:

 let client = Client::new().expect("Failed to create a Client");
 for _ in 0..2 {
    let (tx, rx) = mpsc::channel();

    client.request(url.parse().unwrap(), Dump(tx)).unwrap();
    // wait till done
    let _  = rx.recv();
 }

But I find that only first request handled, the other hung up, the debug log is:

DEBUG:hyper::client::connect: Https::connect("https://http2bin.org/get")
DEBUG:hyper::client::dns: resolve "http2bin.org"
DEBUG:hyper::client::connect: Http::resolved <- ("http2bin.org", Ok(V4(104.131.161.90)))
DEBUG:hyper::client: default Handler.on_control()
DEBUG:hyper::http::h1::parse: writing Headers { Host: http2bin.org, Connection: close, }
DEBUG:hyper::client::response: version=Http11, status=Ok
DEBUG:hyper::client::response: headers=Headers { access-control-allow-origin: *, Content-Length: 196, x-clacks-overhead: GNU Terry Pratchett, Server: h2o/1.7.0, content-type: application/json, access-control-allow-credentials: true, Date: Fri, 06 May 2016 05:57:53 GMT, Connection: close, }
Response: 200 OK
Headers:
access-control-allow-origin: *
Content-Length: 196
x-clacks-overhead: GNU Terry Pratchett
Server: h2o/1.7.0
content-type: application/json
access-control-allow-credentials: true
Date: Fri, 06 May 2016 05:57:53 GMT
Connection: close

{
  "args": {}, 
  "headers": {
    "Connection": "keep-alive", 
    "Host": "http2bin.org", 
    "Via": "1.1 http2bin.org"
  }, 
  "origin": "45.35.21.30", 
  "url": "https://http2bin.org/get"
}
DEBUG:hyper::http::conn: on_remove
DEBUG:hyper::client::connect: Https::connect("https://http2bin.org/get")

I guess this may be a bug. :-)

seanmonstar commented 8 years ago

I'm not sure if I fixed what issue you were facing. I edited the client example just as you did, and received 2 responses.

On Thu, May 5, 2016 at 11:04 PM siddontang notifications@github.com wrote:

Hi

I try to reuse the client, so I change the example client.rs to:

let client = Client::new().expect("Failed to create a Client"); for _ in 0..2 { let (tx, rx) = mpsc::channel();

client.request(url.parse().unwrap(), Dump(tx)).unwrap();
// wait till done
let _  = rx.recv();

}

But I find that only first request handled, the other hung up, the debug log is:

DEBUG:hyper::client::connect: Https::connect("https://http2bin.org/get") DEBUG:hyper::client::dns: resolve "http2bin.org" DEBUG:hyper::client::connect: Http::resolved <- ("http2bin.org", Ok(V4(104.131.161.90))) DEBUG:hyper::client: default Handler.on_control() DEBUG:hyper::http::h1::parse: writing Headers { Host: http2bin.org, Connection: close, } DEBUG:hyper::client::response: version=Http11, status=Ok DEBUG:hyper::client::response: headers=Headers { access-control-allow-origin: , Content-Length: 196, x-clacks-overhead: GNU Terry Pratchett, Server: h2o/1.7.0, content-type: application/json, access-control-allow-credentials: true, Date: Fri, 06 May 2016 05:57:53 GMT, Connection: close, } Response: 200 OK Headers: access-control-allow-origin: Content-Length: 196 x-clacks-overhead: GNU Terry Pratchett Server: h2o/1.7.0 content-type: application/json access-control-allow-credentials: true Date: Fri, 06 May 2016 05:57:53 GMT Connection: close

{ "args": {}, "headers": { "Connection": "keep-alive", "Host": "http2bin.org", "Via": "1.1 http2bin.org" }, "origin": "45.35.21.30", "url": "https://http2bin.org/get" } DEBUG:hyper::http::conn: on_remove DEBUG:hyper::client::connect: Https::connect("https://http2bin.org/get")

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/hyperium/hyper/issues/783

siddontang commented 8 years ago

I update the newest code and find still not fixed. 😢

Rust version: rustc 1.10.0-nightly (8da2bcac5 2016-04-28) OS: Mac OSX.

siddontang commented 8 years ago

I try to use one DNS worker and find it works now, very strange.

fn register(&mut self, reg: Registration) {
        self.dns = Some(Dns::new(reg.notify, 1));
}
siddontang commented 8 years ago

Hi @seanmonstar

I find this may be caused by spmc crate. I use its example adding a sleep after send like:

let (tx, rx) = spmc::channel();

let mut handles = Vec::new();
for n in 0..5 {
    let rx = rx.clone();
    handles.push(thread::spawn(move || {
        let msg = rx.recv().unwrap();
        println!("worker {} recvd: {}", n, msg);
    }));
}

for i in 0..5 {
    tx.send(i * 2).unwrap();
    // If sleep here, the consumer can't receive following data.
    // thread::sleep(Duration::from_millis(100));
}

for handle in handles {
    handle.join().unwrap();
}

If not sleep, it works well.

seanmonstar commented 8 years ago

@siddontang thanks for investigating! I've merged your PR for spmc, and published 0.2.1. A cargo update should pull it in.

siddontang commented 8 years ago

👍 It works now.