3

I want to stream lines out of a file handle and I do not know how to satisfy the trait bound that a File has async_read:

use std::fs::File;
use std::io::{ BufReader, BufRead };
use tokio_core::reactor::Handle;
use tokio_io::io::lines;
use tokio_io::AsyncRead;

struct DockerLog {
    path: String
}

impl DockerLog {
    pub fn new(path: String) -> DockerLog {
        DockerLog {
            path: path
        }
    }
    pub fn read_lines(&self, handle: &Handle) {
        let file : File = File::open(&self.path[..]).unwrap();
        let l = lines(BufReader::new(file));

    }
}

The error:

error[E0277]: the trait bound `std::fs::File: tokio_io::AsyncRead` is not satisfied
  --> src/container/docker_logs.rs:20:17
   |
20 |         let l = lines(BufReader::new(file));
   |                 ^^^^^ the trait `tokio_io::AsyncRead` is not implemented for `std::fs::File`
   |
   = note: required because of the requirements on the impl of `tokio_io::AsyncRead` for `std::io::BufReader<std::fs::File>`
   = note: required by `tokio_io::io::lines`

Looking over the AsyncRead, it seems like a File doesn't mark that it has non-blocking reads. Do I need to downgrade the File to a raw_fd and then do something there?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
xrl
  • 2,155
  • 5
  • 26
  • 40
  • Generally, filesystems *don't* have async IO (or not reliably). Which platform are you on that does? – Shepmaster Jun 01 '17 at 19:44
  • OK, I wasn't aware of that. I'm just targeting Linux. What's the best way of streaming lines from many files? Sounds like I should spawn a thread per file (usually no more than 100 files). – xrl Jun 01 '17 at 20:35
  • Here's a (relatively) recent [article on the support for async file IO in Linux](https://lwn.net/Articles/671649/). The common solution is to have a threadpool and a queue. If you are using Tokio, something like [futures-cpupool](https://crates.io/crates/futures-cpupool) would be the first place I'd turn. – Shepmaster Jun 01 '17 at 20:41
  • 1
    FYI `let file : File = File` is redundant — we don't need to write old-school Java here. `let file = File` is sufficient. – Shepmaster Jun 01 '17 at 20:42
  • 2
    The new tokio release comes with a tokio_fs crate finally supporting async files, see https://tokio.rs/blog/2018-05-tokio-fs/ – Zólyomi István Jun 08 '18 at 14:59
  • @Shepmaster But async IO can be emulated by adding a thread. – porton Nov 02 '21 at 09:52

0 Answers0