Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update to tokio 0.2 and futures 0.3 #134

Merged
merged 12 commits into from
Nov 29, 2019
Merged

Conversation

blckngm
Copy link
Contributor

@blckngm blckngm commented Sep 18, 2019

(Stability note: this feature depends on nightly rust and alpha releases of tokio 0.2 and futures 0.3. Maybe you want to hold off the merge until they are stable. In which case I will try to make sure that this PR is up to date.)

This is a minimal and straightforward update to make inotify up to date with std::task, async-await syntax and next versions of tokio and futures.

API changes

  • EventStream is now a futures 0.3 Stream

    A futures 0.3 Stream can be used with async-await directly (cc Async/Await syntax support #121). See the stream example.

  • The buffer passed to the event_stream method is now required to be Unpin

Other changes

  • Mandatory dependencies is minimized: only tokio-net, tokio-io and futures-core are mandatory dependencies. And for tokio-net unused features are disabled. The full tokio crate and futures-util are dev-dependencies.

  • The crate is updated to 2018 edition, so that related tests and
    examples can be written in async/await.

  • The CI config is modified to:

    • Run on nightly
    • Run with --no-default-features as well

@blckngm blckngm mentioned this pull request Sep 18, 2019
Copy link
Owner

@hannobraun hannobraun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your pull requests, @sopium! This looks really good. I've left a few comments with questions and suggestions.

I'd like to hold off on merging this until everything has become stable.

@hawkw This concerns stuff you've worked on before, and you probably know a lot more about futures/tokio/async than I do. Want to take a look?

Cargo.toml Outdated
libc = "0.2"
mio = { version = "0.6", optional = true }
tokio-io = { version = "=0.2.0-alpha.4", optional = true }
tokio-net = { version = "=0.2.0-alpha.4", optional = true, default-features = false }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the versions are pinned to an exact alpha version. Is there a specific reason for that?

I think requiring an exact version should usually be avoided, as that can cause problems with other crates that might have slightly different version requirements.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These crates might have breaking changes between different alpha versions, so they are pinned to a specific version. It won't be necessary once they are stable.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense.

Cargo.toml Outdated
tempdir = "0.3"
tempdir = "0.3"
futures-util-preview = "=0.3.0-alpha.18"
tokio = "=0.2.0-alpha.4"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above. Versions are pinned.

src/inotify.rs Outdated
@@ -405,7 +405,7 @@ impl Inotify {
pub fn event_stream<T>(&mut self, buffer: T)
-> EventStream<T>
where
T: AsMut<[u8]> + AsRef<[u8]>,
T: AsMut<[u8]> + AsRef<[u8]> + Unpin,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit concerned about the Unpin, as it makes the API less flexible. I think right now one can pass an array, but with the Unpin, you'd either need a slice (possibly causing lifetime issues) or a heap allocation.

I'm not sure if it can be avoided and if that's a big deal in practice. I just figured I'd point out my concerns, in case you have something informative to say :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arrays are Unpin. But your general point is valid.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I didn't think they were!

src/inotify.rs Outdated
@@ -422,7 +422,7 @@ impl Inotify {
pub fn event_stream_with_handle<T>(&mut self, handle: &Handle, buffer: T)
-> io::Result<EventStream<T>>
where
T: AsMut<[u8]> + AsRef<[u8]>,
T: AsMut<[u8]> + AsRef<[u8]> + Unpin,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above about Unpin.

src/stream.rs Outdated
@@ -47,7 +39,7 @@ pub struct EventStream<T> {

impl<T> EventStream<T>
where
T: AsMut<[u8]> + AsRef<[u8]>,
T: AsMut<[u8]> + AsRef<[u8]> + Unpin,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above about Unpin.

src/stream.rs Outdated
@@ -78,36 +70,37 @@ where

impl<T> Stream for EventStream<T>
where
T: AsMut<[u8]> + AsRef<[u8]>,
T: AsMut<[u8]> + AsRef<[u8]> + Unpin,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above about Unpin.

src/stream.rs Outdated
{
if self.unused_bytes == 0 {
let self_ = self.get_mut();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use get_unchecked_mut here, to forgo the requirement for Unpin? I don't think we're moving out of self_, so it should be fine, I think.

@hannobraun
Copy link
Owner

Two more things:

  • Note to my future self: Travis didn't run for some reason. I'll have to figure out why, if it doesn't fix itself at some point.
  • @sopium: For future reference, I'd prefer to have each self-contained change (e.g. the update to Rust 2018) in its own commit. You don't need to change this pull request (it's not a big change anyway), but I'd appreciate it if future pull requests had smaller commits, as those are easier to review.

@hannobraun hannobraun added the status: blocked The issue is currently blocked by something outside this project. label Sep 18, 2019
@hannobraun
Copy link
Owner

Thanks for the change, @sopium! Let's hope things become stable soon, so we can merge this. Until then, more reviews/comments are always welcome.

@peku33
Copy link

peku33 commented Sep 30, 2019

Any updates on this? Waiting for merge! Maybe this could become available as pre-release?
https://stackoverflow.com/questions/46373028/how-to-release-a-beta-version-of-a-crate-for-limited-public-testing
I pretty much need this now and I'm ready to test it

@hannobraun
Copy link
Owner

@peku33 My understanding is, that this still requires nightly. I don't want to merge it as long as this is the case, as I want the master branch to always be in a releasable state (if someone submits a bugfix, for example).

Would it be practical for you to use a Git dependency in Cargo, to depend on @sopium's branch directly?

@peku33
Copy link

peku33 commented Oct 1, 2019

@hannobraun How about doing the same as tokio itself did?
At the moment we have tokio-0.1.22 which is considered stable. We also have tokio-0.2.0-alpha.6 (as of today) which is a pre-release, IIRC requires rust nightly, futures-preview (also alpha). AFAIK, when you use cargo add tokio it will add 0.1.22. But running cargo add tokio --allow-prerelease will install 0.2.0-alpha.6 version. This allows users to choose stable/nightly version pretty easily.
I think keeping current version as stable is reasonable, but why not publish a pre-release (eg 0.8.0-alpha.1 or 1.0.0-alpha.1)?
Current codebase looks pretty stable, since inotify itself won'y probably evolve in the nearest future, there wouldn't probably be more development against current branch.

@hannobraun
Copy link
Owner

@peku33

I think keeping current version as stable is reasonable, but why not publish a pre-release

Because that would take time to do and I don't have much of that. From my perspective, it's a much more economical decision to just wait until everything is stable, then merge and release.

@peku33
Copy link

peku33 commented Oct 4, 2019

Hmm, pretty sad, especially taking into account fact, that lots of popular crates uses such approach (tokio itself, mysql_async etc).

@hannobraun Are you sure accepting @sopium PR with version set to 0.8.0.alpha-1 is too much? This would not automatically update all clients to this unstable version. Even the main version on crates.io etc will still be the current stable version (take a look at https://crates.io/crates/mysql_async ) ;)

@peku33
Copy link

peku33 commented Oct 4, 2019

@sopium Any way to use event_stream with buffer larger than 32 bytes? For now it looks like AsMut<[u8]> accepts arrays of up to 32 bytes...

@blckngm
Copy link
Contributor Author

blckngm commented Oct 5, 2019

@sopium Any way to use event_stream with buffer larger than 32 bytes? For now it looks like AsMut<[u8]> accepts arrays of up to 32 bytes...

You can use Vec<u8>, &mut buf[..], or define a newtype wrapper:

struct LargeU8Array([u8; 512]);

impl AsRef<[u8]> for LargeU8Array {...}

impl AsMut<[u8]> for LargeU8Array {...}

@hannobraun
Copy link
Owner

@peku33

Hmm, pretty sad, especially taking into account fact, that lots of popular crates uses such approach (tokio itself, mysql_async etc).

I guess those crates have less busy maintainers then, because yes, I am sure that adding yet another thing to my plate would be too much.

You haven't commented on my suggestion to add a Git dependency on @sopium's branch in Cargo. Doing so would require no additional work from anyone.

If that's not good enough for some reason (the only one I can think of would be that you want to publish a crate with that dependency to crates.io), you can publish your own version of inotify. Call it peku33-inotify or inotify-async-nightly or whatever. Then anyone else who can't wait for the next version of inotify can use that in the meantime.

@blckngm
Copy link
Contributor Author

blckngm commented Nov 1, 2019

The latest commit is in sync with tokio master.

In tokio master, PollEvented::new now returns io::Result<_>, and PollEvented::new_with_handle is removed. As a result, the event_stream API has changed accordingly.

If you are still using tokio 0.2.0-alpha.6, stick to the previous commit.

@emarcotte
Copy link

emarcotte commented Nov 4, 2019

I'm not exactly fluent in all the ins/outs of the new async stuff. Is it reasonable to implement EventStream as a FusedStream to be more compatible with select!()? E.g. https://rust-lang.github.io/async-book/06_multiple_futures/03_select.html
~~I'm not sure if I should be wrapping it externally or if the stream itself should track a terminated flag... ~~
EDIT: I just saw StreamExt has fuse(). Woopsie!. Can't wait for the docs to catch up a bit :)

@blckngm
Copy link
Contributor Author

blckngm commented Nov 27, 2019

Updated to tokio v0.2.1.

The event_stream_with_handle method is removed becuase PollEvented no longer has new_from_handle.

@hannobraun
Copy link
Owner

Thank you @sopium for your continued work on this! The changes look good to me, but for some reason, the CI build doesn't run. I've set up GitHub Actions instead. Can you please rebase on master, so it runs for this pull request?

@hannobraun hannobraun removed the status: blocked The issue is currently blocked by something outside this project. label Nov 28, 2019
`EventStream` is now a futures 0.3 stream (backed by tokio 0.2) and can
be used with async/await. The stream example is updated accordingly.

The crate is updated to the 2018 edition, so that related tests and
examples can be written in async/await.

The CI config is modified to:
* Run on nightly
* Run with `--no-default-features` as well
tokio 0.2.0-alpha.6
futures 0.3.0-alpha.19
@blckngm blckngm force-pushed the master branch 2 times, most recently from 3027d92 to 60dcd82 Compare November 28, 2019 20:38
@hannobraun hannobraun merged commit abd7936 into hannobraun:master Nov 29, 2019
@hannobraun
Copy link
Owner

Thank you, @sopium! I'll try to release a new version soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants