私はいくつかの重い操作を実行する複数のスレッドがあり、私は仕事中にクライアントを使用する必要があります。私はHTTPクライアントとしてHyper v0.11を使用していますので、接続を開いたままにするために(keep-alive
モード)同じhyper::Client
を共有する必要があるように、接続を再利用したいと思います。別のスレッドからhyper :: clientを使用するにはどうしたらいいですか?
クライアントはスレッド間で共有できません(Sync
またはSend
を実装していません)。ここで私が何をしてきたコードの小さなスニペット:このコードはコンパイルされません
let mut core = Core::new().expect("Create Client Event Loop");
let handle = core.handle();
let remote = core.remote();
let client = Client::new(&handle.clone());
thread::spawn(move || {
// intensive operations...
let response = &client.get("http://google.com".parse().unwrap()).and_then(|res| {
println!("Response: {}", res.status());
Ok(())
});
remote.clone().spawn(|_| {
response.map(|_| {() }).map_err(|_| {() })
});
// more intensive operations...
});
core.run(futures::future::empty::<(),()>()).unwrap();
:
thread::spawn(move || {
^^^^^^^^^^^^^ within `[clos[email protected]/load-balancer.rs:46:19: 56:6 client:hyper::Client<hyper::client::HttpConnector>, remote:std::sync::Arc<tokio_core::reactor::Remote>]`, the trait `std::marker::Send` is not implemented for `std::rc::Weak<std::cell::RefCell<tokio_core::reactor::Inner>>`
thread::spawn(move || {
^^^^^^^^^^^^^ within `[[email protected]/load-balancer.rs:46:19: 56:6 client:hyper::Client<hyper::client::HttpConnector>, remote:std::sync::Arc<tokio_core::reactor::Remote>]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::RefCell<hyper::client::pool::PoolInner<tokio_proto::util::client_proxy::ClientProxy<tokio_proto::streaming::message::Message<hyper::http::MessageHead<hyper::http::RequestLine>, hyper::Body>, tokio_proto::streaming::message::Message<hyper::http::MessageHead<hyper::http::RawStatus>, tokio_proto::streaming::body::Body<hyper::Chunk, hyper::Error>>, hyper::Error>>>>`
...
remote.clone().spawn(|_| {
^^^^^ the trait `std::marker::Sync` is not implemented for `futures::Future<Error=hyper::Error, Item=hyper::Response> + 'static`
は異なるスレッドから同じクライアントを再利用する方法またはいくつかの他はありますアプローチ?
ご回答いただきありがとうございます。私は別のスレッドからの再利用接続が使えないという事実に同意していません、あなたは先物に基づいたスキーマ(Akka HTTPのScalaに似ています)を持っていれば、未来の束を保つことができます。要求に依存する。これは、同じイベントループ内にすべてがある場合、tokioでうまくいきますが、リクエストhttpのようなタスクを外部イベントループに送信する簡単な方法はありません。 – cspinetta
多くのスレッドが何をしているのか説明していません。これまでのところ、XY問題のように聞こえます。あなたは、マルチスレッド化されたタスクの結果を、他の方法ではなくクライアントのスレッドに移すことを検討しましたか? –
はい、そうです、これはユースケースです:私はいくつかの暗号化と復号化操作(主に集中操作です)を備えた最小限のロードバランサを構築しています。接続、HTTPクライアントとしてのn回のイベントループを処理するためのスレッドプール。私はそれを達成するのが非常に難しいと感じました。今はN個のイベントループしかなく、それぞれがtcp接続を受け取り、トークンを復号します。いくつかの要求を実行します。しかし、これは良い方法ではないと私は思う。 – cspinetta