shio-rs icon indicating copy to clipboard operation
shio-rs copied to clipboard

Proxy example should use per-thread client

Open algermissen opened this issue 8 years ago • 6 comments

If I am not mistaken, the example regarding the proxying solution will create a new client per request in https://github.com/mehcode/shio-rs/blob/master/examples/proxy/src/main.rs#L19

If I am correct - how would this be done with a per-thread client?

algermissen avatar Sep 22 '17 22:09 algermissen

I am also curious about how one would do this with shio...

There is a pattern where you put a core's handle in thread local storage, and then you can put a hyper/reqwest Client in TLS as well based on that handle, but it doesn't seem like that could be used here.

kardeiz avatar Oct 04 '17 21:10 kardeiz

That's basically what it's done here : the Context have the thread core handle, and it create a hyper::Client future on that handle. No thread-local storage involved here.

Meralis40 avatar Oct 06 '17 06:10 Meralis40

But that is the point: the Client should be put in thread-local storage (or made reusable in some other way), to take advantage of the internal connection pool, keep-alive (optionally), etc.

kardeiz avatar Oct 06 '17 12:10 kardeiz

I definitely agree that this should be easily possible. A quick work around for a limitation here would be to use a ThreadLocal.

lazy_static! {
    pub static CLIENT: ThreadLocal<hyper::Client> = ThreadLocal::new();
}

// [...]
CLIENT.get_or(Client::new).get("....");

mehcode avatar Oct 07 '17 03:10 mehcode

That doesn't seem to be quite that straightforward 😕 :

17 | / lazy_static! {
18 | |     pub static ref CLIENT: ThreadLocal<Client<HttpConnector>> = ThreadLocal::new();
19 | | }
   | |_^ `std::rc::Rc<std::cell::RefCell<hyper::client::pool::PoolInner<tokio_proto::util::client_proxy::ClientProxy<tokio_proto::streaming::message::Message<hyper::proto::MessageHead<hyper::proto::RequestLine>, hyper::Body>, tokio_proto::streaming::message::Message<hyper::proto::MessageHead<hyper::proto::RawStatus>, tokio_proto::streaming::body::Body<hyper::Chunk, hyper::Error>>, hyper::Error>>>>` cannot be sent between threads safely

hobofan avatar Oct 12 '17 09:10 hobofan

Maybe use std thread_local! ?

thread_local! {
    static CLIENT : RefCell<Option<Client>>,
}

fn client_start<F>(handle: &Handle, callback: F) -> hyper::client::FutureResponse 
where F: Fn(&Client) -> hyper::client::FutureResponse
{
    CLIENT.with(|rf| {
        let should_be_init = rf.borrow().is_none();
        if should_be_init {
            *rf.borrow_mut() = Some(Client::new(handle));
        }
        callback(rf.borrow().as_ref().unwrap())
    })
}

Meralis40 avatar Oct 13 '17 12:10 Meralis40