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

Control if redis uses async-std or tokio via feature flags #4

Merged
merged 9 commits into from
Aug 30, 2023

Conversation

hgzimmerman
Copy link
Contributor

I saw that this project was pulling in async-std in as a dependency. My project didn't otherwise use async-std, instead using tokio, and would prefer to avoid async-std if possible.

So to preserve the current behavior, I pulled out async-std-comp into its own feature flag and made it the default. I then tested this against my project that was already using rslock, setting default-features = false and features = ["tokio-comp"] and found that it was functionally the same, and saved me from compiling ~15 dependencies I evidently didn't need.

Since you directly depend on tokio anyways, I'm curious if the default shouldn't be tokio-comp instead of async-std-comp to avoid pulling in both, since downstream projects likely only include one or the other. Thoughts?

@hgzimmerman
Copy link
Contributor Author

hgzimmerman commented Aug 25, 2023

I have noticed a regression when dropping the lock guard, where when dropping it, it locks up tokio when doing the futures::executor::block_on call to unlock.
I believe that this discussion captures what I'm seeing tokio-rs/tokio#2653.

I will attempt to conditionally compile either futures::executor::block_on or tokio::task::spawn_blocking in the Drop impl depending on which is enabled.

Edit: But now I realize that this creates a situation where we must either ensure mutually-exclusive feature-flags, so as to not have both sections of code run, causing the same regression if a transitive dependency sets async-std-comp when you are using tokio anyways; or only conditionally compile acquire and its guard when async-std-comp and not tokio-comp is selected.


At the moment, because there isn't a good story for mutually-exclusive features in cargo, I'm going to opt to compile out acquire when using tokio-comp

@hgzimmerman
Copy link
Contributor Author

I added an acquire_no_guard function to allow looping until a lock is acquired so downstream crates don't have to re-implement that themselves if they use the tokio-comp feature.

I would prefer acquire_guard to be the name of the function that returns a guard and acquire to be the name of the function that returns the plain lock, but for the sake of backwards compatibility, I have left acquire the same here.

Now, acquire() cannot be called if the tokio-comp feature is enabled, preventing the deadlock of Tokio's runtime.

Copy link
Owner

@hexcowboy hexcowboy 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 taking the time to research and optimize this library. your brief on tokio blocking makes sense.

to prevent users from getting compilation errors when using no-default-features in their Cargo.toml, you should add this guard before LockManager: #[cfg(any(feature = "async-std-comp", feature = "tokio-comp"))]

additionally, please run a cargo fmt to satisfy ci

thanks :)

src/lock.rs Outdated Show resolved Hide resolved
src/lock.rs Show resolved Hide resolved
@hgzimmerman
Copy link
Contributor Author

Hello, thanks for working with me to integrate this change.

I've done my best to make the changes you requested. I differed by putting #[cfg(any(feature = "async-std-comp", feature = "tokio-comp"))] on the lock module instead of the LockManager struct because other structs rely on that struct anyways, making the module practically unusable without them. Applying the cfg condition to the module seems like a cleaner approach.

@hgzimmerman
Copy link
Contributor Author

hgzimmerman commented Aug 30, 2023

I see the issue, the test suite runs with --all-features, causing the not(tokio-cfg) dependent cfg to compile out the Drop impl. I will add cfgs to the test, and duplicate the test and alter the expected outcome if running with only async-std.

@hgzimmerman
Copy link
Contributor Author

This is imperfect, because the test suite doesn't cover the currently failing test now.

I figure I should extend the workflow to test with different feature flags, but I'm unsure exactly how you want that to be done.

I figure having a single stable-toolchain job without the --all-features flag to get the default crate behavior would be acceptable?

@hexcowboy
Copy link
Owner

I figure having a single stable-toolchain job without the --all-features flag to get the default crate behavior would be acceptable?

good point, i am happy to accept this proposed stable-toolchain job to ensure tests run with default features

@hexcowboy hexcowboy merged commit 4de6748 into hexcowboy:main Aug 30, 2023
12 checks passed
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.

2 participants