smol-rs / async-fs

Async filesystem primitives
Apache License 2.0
131 stars 8 forks source link

Consider making File `Sync` #2

Closed ririsoft closed 4 years ago

ririsoft commented 4 years ago

Hello,

I am trying to migrate my code from async_std to async_fs and I am encountering issues with File not being Sync in async_fs while it is in async_std.

This is a concern for usage with Tide, for instance, which only supports Send + Sync for setting a response body:

async {
    let file = async_fs::File::open("foobar").await.unwrap();
    let file = futures_lite::io::BufReader::new(file);
    let mut res = tide::Response::new(tide::StatusCode::Ok);
    res.set_body(tide::Body::from_reader(file, None));
}

Is there any chance to have File being Sync, please ? Otherwise what workaround would you recommend, please ? Wrapping the whole into an Arc is a pain to implement in async world.

Thanks in advance ! (Do not hesitate to tell if you are tired will all the beginners issue I opened those days on your various projects...) Cheers.

ghost commented 4 years ago

Can you do cargo update -p blocking and try again? I have just published blocking v0.5.2 that implements Sync for Unblock, which is what async_fs::File internally uses.

ririsoft commented 4 years ago

Updated and fixed, thank you very much! Migrating my code to async-fs was very straighforward. I really like your approach to just bring the minimal over the standard library.

What surprises me is that while using async-fs I am not hit by https://github.com/stjepang/blocking/issues/10. I have not gone deeper on this, but I would like to understand if I can safely use the full seek utilities with an async_fs::File, including SeekFrom::Currrent.

ghost commented 4 years ago

You can use full seek utilities :) The 'secret sauce' is this poll_reposition() function that fixes the file cursor after read operations:

https://github.com/stjepang/async-fs/blob/3fe8e5a3b98954f69a519410985ce1231b016c9a/src/lib.rs#L1121

Since Unblock::poll_read() will read more data than we request, we keep track of how much data was actually consumed in async code. If we then try seeking or writing, the file cursor will be first repositioned to the true offset.