-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: add smol runtime support with TCP and QUIC transports #6235
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
base: master
Are you sure you want to change the base?
feat: add smol runtime support with TCP and QUIC transports #6235
Conversation
Add smol 2.0 as an optional dependency and implement SmolExecutor to enable using the smol async runtime with libp2p-swarm. Changes: - Add smol 2.0 dependency with platform guards (excluding emscripten, wasi, unknown) - Implement SmolExecutor that spawns futures using smol::spawn().detach() - Add with_smol_executor() method to Config following tokio pattern - Add smol feature flag to enable the executor The implementation mirrors the existing TokioExecutor pattern with identical platform exclusions and feature gating.
Add Smol provider type and with_smol() method to SwarmBuilder, enabling users to configure libp2p with the smol async runtime. Changes: - Add Smol enum as runtime provider marker type - Implement with_smol() method in ProviderPhase following tokio pattern - Add swarm config macro invocation for Smol provider - Use same platform guards as tokio (non-wasm32 only) The implementation follows the existing type-state builder pattern and will be wired up with the top-level smol feature flag in a subsequent commit.
Implement smol runtime support for TCP transport using async-io. Changes: - Add async-io 2.0 as optional dependency for async I/O primitives - Add smol feature flag that enables async-io and if-watch/smol - Create provider/smol.rs module following tokio provider pattern - Implement Provider trait for Tcp using async_io::Async wrappers - Export smol module publicly when feature is enabled - Add SwarmBuilder integration via impl_tcp_builder macro The implementation mirrors the tokio provider architecture: - TcpStream wraps async_io::Async<net::TcpStream> - TcpListener wraps async_io::Async<net::TcpListener> - IfWatcher uses if_watch::smol::IfWatcher - Handles connection readiness via async-io's readable/writable API
Implement smol runtime support for QUIC transport using async-io. Changes: - Add async-io 2.0 as optional dependency - Add smol feature flag that enables async-io, if-watch/smol, and quinn/runtime-smol - Add Runtime::Smol variant to Runtime enum - Create provider/smol.rs module following tokio provider pattern - Implement Provider trait using if_watch::smol::IfWatcher - Use async_io::Timer for sleep implementation - Use async_io::Async for UDP socket operations - Add SmolRuntime support in new_endpoint match arm - Export smol module publicly when feature is enabled - Add SwarmBuilder integration via impl_quic_builder macro The implementation mirrors the tokio provider architecture and leverages quinn's SmolRuntime for QUIC protocol support.
Add top-level smol feature flag that enables smol runtime support across the libp2p ecosystem. Changes: - Add smol feature to libp2p Cargo.toml - Cascade smol feature to libp2p-swarm (required) - Cascade smol feature to libp2p-tcp (optional, when tcp feature enabled) - Cascade smol feature to libp2p-quic (optional, when quic feature enabled) The feature follows the same pattern as the existing tokio feature, enabling users to opt into smol runtime support with a single feature flag: `features = ["smol", "tcp", "quic"]` This completes the smol runtime integration, providing full feature parity with tokio for TCP and QUIC transports.
Add the missing poll_write_vectored method to the TCP smol provider's AsyncWrite implementation for TcpStream. This enables vectored I/O optimization matching the tokio provider implementation, preventing fallback to multiple poll_write calls. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add compile_error! checks to prevent both `tokio` and `smol` features from being enabled simultaneously in libp2p-swarm, libp2p-tcp, and libp2p-quic crates. This follows Cargo's recommended approach for handling mutually exclusive features as documented in: https://doc.rust-lang.org/cargo/reference/features.html#mutually-exclusive-features 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add macro impl_tcp_phase_with_quic to provide with_quic() and with_quic_config() methods on TcpPhase for both Tokio and Smol providers. This allows users to skip TCP and go directly to QUIC when using the smol runtime. Previously, with_quic() on TcpPhase was only available for Tokio, causing a compilation error when trying to use: SwarmBuilder::with_smol().with_quic() 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
b401729 to
f23f3cc
Compare
|
Is there a reason to do this besides "it can be done"? Is there any large project that wants to forgo tokio? What's their reasoning? |
I need this for mobile development. Tokio uses its own futures implementation which doesn't integrate well with Swift/Kotlin/Dart async runtimes. Smol uses standard Rust futures, making cross-language FFI much simpler. This benefits the mobile ecosystem broadly. |
jxs
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, and thanks for the interest.
I need this for mobile development. Tokio uses its own futures implementation which doesn't integrate well with Swift/Kotlin/Dart async runtimes. Smol uses standard Rust futures, making cross-language FFI much simpler.
can you elaborate on this? Tokio runs std::future::Future implementations on its executor
Why
This PR adds support for the smol async runtime as an alternative to tokio, enabling users who prefer smol's lightweight, modular design to use libp2p without pulling in tokio dependencies.
Approach
Followed the existing tokio implementation patterns exactly:
SmolExecutorimplementing theExecutortrait usingsmol::spawn().detach()Smolprovider marker type andwith_smol()builder methodasync-io2.0 for async I/O primitivesruntime-smolfeaturelibp2pcrateBreaking Changes
None
Testing
Usage
Scope
with_smol())🤖 Generated with Claude Code