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

Implement tokio support #2

Merged
merged 4 commits into from
Oct 15, 2020
Merged

Implement tokio support #2

merged 4 commits into from
Oct 15, 2020

Conversation

jmagnuson
Copy link
Contributor

Adds dependencies tokio + futures behind 'tokio' feature.

Implements tokio::UnixSeqpacketConn and tokio::UnixSeqpacketListener for supporting SEQPACKET sockets in Tokio.

Closes #1.


Much of this roughly follows how tokio UnixStream/Listeners (SOCK_STREAM) are set up, but attempts to adopt some of the existing API naming used by uds. However, I'm totally open to other naming conventions, or module organization for that matter.

My immediate use-case is for UnixSeqPacketConn, but have also introduced (perhaps a bit more roughly) the Listener type for the sake of some sort of completeness.

Cargo.toml Outdated

[target."cfg(unix)".dev-dependencies]
tempdir = "0.3"
tokio_02 = {package="tokio", version = "0.2", features = ["macros", "rt-core", "test-util"]}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ideally this would be optional as well, but I don't think Cargo allows optional dev-dependencies. Thus, it's either forcing these tokio test-related features for non-test builds, or forcing all test builds to take a tokio dependency.

Copy link
Owner

Choose a reason for hiding this comment

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

I know 😞
This is by the way why the minimal-versions job is failing.
Either try to find the earliest patch version of tokio where cargo check -Z minimal-versions passes, or if the latest version doesn't pass either then remove the cargo test part of that job.

What's worse is that those feature flags added under dev-dependencies are also implicitly enabled for regular builds that enable that feature. For that reason i enable test-only mio_07 features through RUSTFLAGS in .cirrus.yml, .travis.yml and tests/test_{locally,target}.sh. While doing this might be pedantic since most final executables are going to want those features anyway, it could make those crates break when/if -Z features=dev_dep (which fixes that bug) becomes the default.

Copy link
Owner

Choose a reason for hiding this comment

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

What do you think about moving the dev dependency features to RUSTFLAGS? If it's not pointless I can do that later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting; I wasn't aware of this issue, or workaround. I tried moving the dev features to RUSTFLAGS, but had some issues with macros and tokio's failure to pull in the tokio-macros sub-crate:

$ RUSTFLAGS='--cfg feature="os-poll" --cfg feature="rt-core" --cfg feature="macros"' cargo test --all-features

...

error[E0432]: unresolved import `tokio_macros`
   --> /home/jon/.cargo/registry/src/gh.neting.cc-1ecc6299db9ec823/tokio-0.2.22/src/lib.rs:403:13
    |
403 |     pub use tokio_macros::select_priv_declare_output_enum;
    |             ^^^^^^^^^^^^ use of undeclared type or module `tokio_macros`

(note, I realized that test-util isn't actually used, so that will be dropped regardless of the outcome of this)

One workaround is just importing tokio-macros itself into dev-dependencies, and then setting up tests such that:

#[tokio_macros::test]
async fn test_listener_accept() {
    ...
}

which isn't something I've really seen other crates do (especially in documentation, which exclusively uses tokio::main), but I couldn't come up with a better solution offhand.

Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's also cargo-hack which looks to address these limitations in cargo. I did a quick trial run and it didn't seem to like running test with --all-features, but worked as expected when I wrote everything out manually:

$ cargo hack --features="mio_07,tokio,tokio_02/macros,tokio_02/rt-core,mio_07/os-poll" test

Copy link
Owner

Choose a reason for hiding this comment

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

Thanks for the attempt. We'll just have to accept it being enabled for now.
(by the time I'm releasing v1.0 of this it will probably have been fixed in cargo :)

cargo-hack looks interesting but feels too complex.

@jmagnuson
Copy link
Contributor Author

I'll add notes to the README and determine what needs to be done to satisfy OSX CI, but any interim reviews would be appreciated.

src/tokio/seqpacket.rs Outdated Show resolved Hide resolved
Copy link
Owner

@tormol tormol left a comment

Choose a reason for hiding this comment

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

Thanks!

You probably also need to update the MSRV to what tokio or futures require.
(The next uds release will be a major version due to other changes anyway).

Do you plan to add more methods? If not I'll add bind_unix_addr() and the like later.

Cargo.toml Outdated

[target."cfg(unix)".dev-dependencies]
tempdir = "0.3"
tokio_02 = {package="tokio", version = "0.2", features = ["macros", "rt-core", "test-util"]}
Copy link
Owner

Choose a reason for hiding this comment

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

I know 😞
This is by the way why the minimal-versions job is failing.
Either try to find the earliest patch version of tokio where cargo check -Z minimal-versions passes, or if the latest version doesn't pass either then remove the cargo test part of that job.

What's worse is that those feature flags added under dev-dependencies are also implicitly enabled for regular builds that enable that feature. For that reason i enable test-only mio_07 features through RUSTFLAGS in .cirrus.yml, .travis.yml and tests/test_{locally,target}.sh. While doing this might be pedantic since most final executables are going to want those features anyway, it could make those crates break when/if -Z features=dev_dep (which fixes that bug) becomes the default.

src/tokio/seqpacket.rs Outdated Show resolved Hide resolved
src/tokio/seqpacket.rs Outdated Show resolved Hide resolved
src/tokio/seqpacket.rs Outdated Show resolved Hide resolved
src/tokio/seqpacket.rs Outdated Show resolved Hide resolved
src/tokio/seqpacket.rs Outdated Show resolved Hide resolved
@jmagnuson
Copy link
Contributor Author

I went ahead and rebased the shutdown change (4d6c2c9) to go before everything else, resulting in a force-push. However, I left the existing changeset otherwise in-tact so that the subsequent fixup commits could be reviewed.

Do you plan to add more methods?

I think it might be best to leave that out for this initial pass. Not trying to push work onto you, but honestly you would probably get the tokio sockets up to parity a lot faster than I could. There's still the larger question of what to do about AsyncRead/Write traits that this PR should nail down first. And... making CI happy :(

Copy link
Owner

@tormol tormol left a comment

Choose a reason for hiding this comment

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

Thanks for rebasing.
After changing the MSRV documentation, you can squash the later commits into one commit adding stream and another adding listener.

Sorry for being slow to respond. I was traveling last weekend and have been working late.

src/tokio/seqpacket.rs Outdated Show resolved Hide resolved
Cargo.toml Outdated

[target."cfg(unix)".dev-dependencies]
tempdir = "0.3"
tokio_02 = {package="tokio", version = "0.2", features = ["macros", "rt-core", "test-util"]}
Copy link
Owner

Choose a reason for hiding this comment

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

What do you think about moving the dev dependency features to RUSTFLAGS? If it's not pointless I can do that later.

README.md Outdated
## Minimum Rust version

The minimum Rust version is 1.36, because of `std::io::IoSlice`.
If this is a problem I can make the parts that need it opt-out.
The minimum Rust version is 1.39, because of the MSRV of both `tokio` and `futures`.
Copy link
Owner

Choose a reason for hiding this comment

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

Since those dependencies are optional, this makes it unclear what the minimum supported version is when not enabling the tokio feature. Either don't mention the reason or add that the minimum version is 1.36 by default.

@@ -650,6 +662,17 @@ impl NonblockingUnixSeqpacketConn {
// nonblockingness is shared and therefore inherited
Ok(NonblockingUnixSeqpacketConn { fd: cloned.into_raw_fd() })
}

/// Shuts down the read, write, or both halves of this connection.
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
Copy link
Owner

Choose a reason for hiding this comment

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

Thanks for adding shutdown()!

Maybe add a test? (I can do that later though)

@tormol
Copy link
Owner

tormol commented Sep 18, 2020

Forgot to say that the failing test is probably flaky or maybe apple changed something.

@jmagnuson
Copy link
Contributor Author

Went ahead and rebased again to clean things up since there are only one or two remaining items. But the latest changes were:

  • added shutdown tests for blocking, nonblocking, and tokio socket variants.
  • removed AsyncRead/Write impls
  • reworded MSRV to exclude mentioning tokio
  • removed test-util feature inclusion from tokio

Let me know your thoughts how what to do about RUSTFLAGS and tokio's macros feature, or if you want to punt and figure out what works best at a later time.

Sidenote: you may be right about CI flakiness. I see the latest commit c48d0af has passed, but I didn't make any explicit changes for that to happen..

@jmagnuson
Copy link
Contributor Author

@tormol any further thoughts? Tokio is also on the verge of releasing 0.3 (which will invariably resemble 1.0 more closely than 0.2) so that is something to consider.

@tormol
Copy link
Owner

tormol commented Oct 15, 2020

THANK YOU.

Sorry for being so slow to respond again.
(I lacked motivation to think about code outside of work for a while, but kept thinking I'd do it in a few days).
Now that I'm likely finished looking for an apartment to buy that will hopefully change.)

@tormol tormol merged commit 79f3336 into tormol:master Oct 15, 2020
@jmagnuson jmagnuson deleted the feature/tokio branch October 15, 2020 22:47
@jmagnuson
Copy link
Contributor Author

No worries at all-- know that feeling all too well, and I actually just had my first child in September, so my OSS work has been pretty inconsistent as well. Glad to see the PR make it across the finish line though!

@tormol
Copy link
Owner

tormol commented Oct 16, 2020 via email

@tormol
Copy link
Owner

tormol commented Oct 21, 2020

0.2.0 is now released.

When I tested on Illumos, the test binaries created by cargo test --features tokio failed to start due to a missing symbol. I've just noted that in a feature table I've added to the README, but it could just be because I haven't updated that VM (OmniOS) in a while.

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.

Tokio support
2 participants