Deprecate `async_std` support
Description
Moving this into a separate issue to increase awareness.
We are planning to deprecate support for async_std throughout all of rust-libp2p.
See prior discussion in https://github.com/libp2p/rust-libp2p/issues/4449#issuecomment-2490995499 and https://github.com/libp2p/rust-libp2p/issues/3515#issuecomment-2443830862.
If anyone still depends on it, please comment in this issue.
Depends on #4449.
Motivation
async-std has officially be discontinued and tokio has become the de-factor standard async runtime in the ecosystem.
Current Implementation
We currently support two runtimes, tokio and async_std. tokio is already the default in most examples/ tests.
Implementation-wise, this concerns the swarm, mDNS, and the transports TCP, QUIC and DNS.
Open Question
Copying from https://github.com/libp2p/rust-libp2p/issues/3515#issuecomment-2734256901:
We then have to make a decision on whether we will in the future only support
tokio, or still want to be open to support other runtimes, e.g.smolthat is recommended byasync_stdas alternative. Right now we have in many transports, like tcp, aProviderabstraction for the different runtimes. If we'll only support tokio we could get rid of this abstraction, but under the risk of having to re-add it once there is a demand to an alternative to executor.
Are you planning to do it yourself in a pull request?
Maybe
Copying over @dariusc93 comment from https://github.com/libp2p/rust-libp2p/issues/3515#issuecomment-2734303364:
But I think we then have to make a decision on whether we will in the future only support tokio, or still want to be open to support other runtimes, e.g.
smolthat is recommended byasync_stdas alternative.I would have to double check but we could an
SmolExecutorif there is not one already and add it apart ofSwarmBuilder, but I am all for just deprecatingasync-stdwithout adding smol or additional executors as well (though others may have different opinions for that, which I am all for hearing)Right now we have in many transports, like tcp, a
Providerabstraction for the different runtimes. If we'll only support tokio we could get rid of this abstraction, but under the risk of having to re-add it once there is a demand to an alternative to executor.Im all for of keeping the abstractions and supporting multiple runtimes, either what we would support in our protocols or by allowing the user to supply their own runtime, though we should probably continue to prefer tokio (or
wasm-bindgen-futuresfor wasm32 arch) while still leaving the abstraction for others to bring their own runtime if needed. That way we can avoid re-adding the abstractions in the future unless we are dead-set on using tokio through and through, though we would never know for sure if something would replace tokio in the future.
Copying over @jxs comment from https://github.com/libp2p/rust-libp2p/issues/3515#issuecomment-2734350358:
But I think we then have to make a decision on whether we will in the future only support tokio, or still want to be open to support other runtimes, e.g. smol that is recommended by async_std as alternative.
Thanks for bringing this Elena, yeah we probably need to address it.
Right now we have in many transports, like tcp, a Provider abstraction for the different runtimes. If we'll only support tokio we could get rid of this abstraction, but under the risk of having to re-add it once there is a demand to an alternative to executor.
true but tbh it seems the days of new runtimes are over,
tokiohas now become the de facto runtime right?smolhas 300k downloads per month,tokiohas 13 millionIMHO we'd just remove
async-stdcode and stick totokio, if anyone needssmolfor a particular transport they can have and maintain a fork on their own repos, we can link to if if needed wdyt? But is there anyone still usingasync-std? cc @lyzkov since you were the only one commenting on https://github.com/libp2p/rust-libp2p/issues/4449#issuecomment-2507713803.
IMHO we'd just remove async-std code and stick to tokio, if anyone needs smol for a particular transport they can have and maintain a fork on their own repos, we can link to if if needed wdyt? But is there anyone still using async-std?
So that means we would remove the abstractions that support different runtimes, or would we keep those in place?
I would like to keep the abstraction layer to make it easier for users who wants to make an adapter, but not very strongly. Rust has zero-cost abstractions right? There won't be additional cost in runtime with no dynamic dispatch, but silghtly more code for us to maintain.
If what we really want is to simply reduce dependency tree, just remove async_std and keep the abstractions. But if we also want to maintain less code, remove the abstractions as well.
EDIT: I personally have never used async_std or smol so no feelings about them.
I would like to keep the abstraction layer to make it easier for users who wants to make an adapter, but not very strongly. Rust has zero-cost abstractions right? There won't be additional cost in runtime with no dynamic dispatch, but silghtly more code for us to maintain. If what we really want is to simply reduce dependency tree, just remove
async_stdand keep the abstractions. But if we also want to maintain less code, remove the abstractions as well. EDIT: I personally have never usedasync_stdorsmolso no feelings about them.
Personally for me, i think keeping the abstraction layer would not add any cost and would make it easier for others to implement other runtimes vs forking libp2p and/or the protocols (or utils) and adding it.
yeah it's decided then, you win 😛 Let's leave the abstractions with comments on the why they are still there
@elenaf9 Could I take this issue :) ?
@elenaf9 Could I take this issue :) ?
@gitToki yes, thank you! Would be great to have a separate PR per crate that is affected, makes it easier to review.
What is the benefit of deprecating vs removing it? I've read some discussions in the past and there weren't ever compelling arguments to keep async-std.
Just remove it already, those who need time to migrate can continue to use older version and maybe if there is a critical vulnerability worth fixing then a patch to 0.55.x series can be issued to help those users.
As to abstractions, zero cost doesn't mean "free". It only means it is as efficient as you could have written it yourself. And supporting two runtimes might require boxing things, adding branches and other complications that inherently wouldn't be there if only single runtime was supported.
Does anyone advocating for keeping abstractions really intend to integrate a custom async runtime, considering that even async-std ended up mostly unneeded in the ecosystem? If no I'd probably advocate for pruning abstractions too (though I didn't dig much into the code to see what it implies in practice).
Also note that if there isn't a second runtime present, it is likely that those abstractions might end up being unsuitable for other custom runtimes anyway. For example both async-std and tokio have "implicit" context (global and thread-local accordingly) and some runtimes require an explicit handle, which already makes current abstractions insufficient, at least without hacks from one of both ends.
Does anyone advocating for keeping abstractions really intend to integrate a custom async runtime
Personally I don't. I am not planning to use a runtime other than tokio nor have ever used before.
EDIT: I was going to comment on the issue that we should also contact our major users like Nazar and Daniel, great that you show up.
@dariusc93 @elenaf9 @jxs what are your opinion on that ?
What is the benefit of deprecating vs removing it?
A deprecation is nicer for users. Rather than getting a lot of errors that something doesn't exist (not everyone reads CHANGELOGs), they have a deprecation warning that includes info about how to migrate ("use tokio") and it allows for some time to do the changes without having to block the version upgrade on it.
Does anyone advocating for keeping abstractions really intend to integrate a custom async runtime, considering that even async-std ended up mostly unneeded in the ecosystem? If no I'd probably advocate for pruning abstractions too (though I didn't dig much into the code to see what it implies in practice).
The additional async runtime could also be implemented by a downstream crate, not necessarily by us. But it would require us to make the Provider traits public, which it currently isn't the case in all crates.
Also note that if there isn't a second runtime present, it is likely that those abstractions might end up being unsuitable for other custom runtimes anyway. For example both async-std and tokio have "implicit" context (global and thread-local accordingly) and some runtimes require an explicit handle, which already makes current abstractions insufficient, at least without hacks from one of both ends.
That's a valid point.
I would propose to soft-deprecate async_std support now. If after the release there are major complaints we keep the abstractions and make relevant traits public so users can keep maintaining their own executor downstream. If not we remove the abstractions together with the full removal of async_std in the release after. Wdyt?
I feel like it is just a lot of effort most likely wasted for maintainers on all of those warnings and reviews. I understand if the APIs change and there is an upgrade path, but in this case it is a major breaking change for async-std without any alternative other than switching to tokio. Seeing the same as warning instead of compilation error (cargo will complain about a feature missing) is not a lot of help IMO, but it does mean delaying removal even further.
If I was an upstream maintainer I'd vote strongly in favor of removal in a new minor version and be done with it. IIRC @jxs was also in favor of removing it during last community call.
@elenaf9 are you OK with me updating PR to delete it ?
Discussed out of band with @jxs and @dariusc93. We agreed to:
- hard deprecate (i.e. remove) support for
async_std, which also unblocks #5968 - keep
Providerabstraction so users can keep maintaining their own executor downstream
@gitToki sorry for the back-and-forth. Could you please update the PRs?
Does this also mean tokio feature can be made enabled by default with default-features = false required to opt-out? I believe that would be a great developer experience upgrade.
Does this also mean
tokiofeature can be made enabled by default withdefault-features = falserequired to opt-out? I believe that would be a great developer experience upgrade.
Correct, especially if they will be bringing their own executor and dont wish to conflict with tokio.
Will update the PR this week, no problem
thanks @gitToki!
Is there any scope for me to work on a part of this? Would love to do so @jxs
Is there any scope for me to work on a part of this? Would love to do so @jxs
@gitToki is already tackling this issue, so they are the best person to tell if any help is still needed. @PoulavBhowmick03 if you are generally interested in contributing, we can also look for another issue for you.
@PoulavBhowmick03 You can take Swarm and TCP if you want to participate, it's ok for you ?
@PoulavBhowmick03 You can take Swarm and TCP if you want to participate, it's ok for you ?
I can definitely take a look into those
Is there any scope for me to work on a part of this? Would love to do so @jxs
@gitToki is already tackling this issue, so they are the best person to tell if any help is still needed. @PoulavBhowmick03 if you are generally interested in contributing, we can also look for another issue for you.
I would love to work on other issues as well, but for now should I look into the specific ones @gitToki mentioned? if that's alright @elenaf9
I would love to work on other issues as well, but for now should I look into the specific ones @gitToki mentioned? if that's alright @elenaf9
Sure 👍
@gitToki I see you have a PR opened related to Swarm. Should I work on that or work independently?
@PoulavBhowmick03 yes you can continue with the PR already opened! for both Swarm and TCP
would like to work on this!
All my PRs are now merged Thanks @elenaf9 and @jxs for all the reviews and for explaining the things I did wrong. I genuinely learned a lot about how libp2p works