Description
Hi – I’m trying to get async file I/O working within a Hyper service, and I’m having trouble getting hold of the event loop handle. I’m not sure if I’m missing something obvious, or if there is something missing from hyper 0.11a0.
(This may be related to #1075, and maybe I’ve just confused myself by using the “easy mode” APIs. If so, perhaps some improved docs / examples of how and when to do things the non-easy way would be helpful.)
I recently wrote a little static file webserver in Rust, which serves the files using async I/O. The crate tokio-file-unix (0.4.0) supports async I/O; all I needed to do was:
let f = std::fs::File::open(path).expect("Couldn't open file");
let file = tokio_file_unix::File::new_nb(f).expect("Couldn't set nonblocking");
let reader = file.into_reader(&handle).expect("Fail to generate reader");
// … and then you can use tokio_io::io::read(reader, buf) to read data from the file.
However, tokio_file_unix::File::into_reader
needs to be provided with a tokio::reactor::handle
(a handle to the current event loop), which it ultimately passes to tokio::reactor::PollEvented::new
.
My problem is that I can’t see how to get hold of that handle!
As far as I can see, hyper::server::Http::bind()
just passes an http::request::Request
to the enclosed tokio_service::Service
. There is no mention of handles.
To work around this, I forked hyper and made the following change. As you can see, it does the following:
hyper::server::Http::bind_connection
now stores a clone of the currentHandle
in theHttpService
struct.- The
Service
’sRequest
is now a pair(http::request::Request, tokio::reactor::Handle)
rather than just anhttp::request::Request
. HttpService::call
now passes a clone of theHandle
(from theHttpService
struct) to the service.
That’s obviously not the right solution. Am I missing something obvious, or is there something missing from Hyper at the moment?
Thanks.