-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add smol as an executor #3790
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: main
Are you sure you want to change the base?
Add smol as an executor #3790
Conversation
# Conflicts: # .github/workflows/sqlx.yml
680a7b9
to
5627ca8
Compare
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.
General note: because async-std
and smol
share a lot of the same constituent crates, it would save us a lot of code deduplication to just use those crates directly where possible (namely async-io
).
} else if #[cfg(feature = "_rt-smol")] { | ||
use smol::net::resolve; | ||
use smol::Async; | ||
use std::net::TcpStream; | ||
|
||
let mut last_err = None; | ||
|
||
// Loop through all the Socket Addresses that the hostname resolves to | ||
for socket_addr in resolve((host, port)).await? { | ||
let stream = Async::<TcpStream>::connect(socket_addr) | ||
.await | ||
.and_then(|s| { | ||
s.get_ref().set_nodelay(true)?; | ||
Ok(s) | ||
}); | ||
match stream { | ||
Ok(stream) => return Ok(with_socket.with_socket(stream).await), | ||
Err(e) => last_err = Some(e), | ||
} | ||
} | ||
|
||
#[cfg(not(feature = "_rt-async-std"))] | ||
{ | ||
crate::rt::missing_rt((host, port, with_socket)) | ||
// If we reach this point, it means we failed to connect to any of the addresses. | ||
// Return the last error we encountered, or a custom error if the hostname didn't resolve to any address. | ||
Err(match last_err { | ||
Some(err) => err, | ||
None => io::Error::new( | ||
io::ErrorKind::AddrNotAvailable, | ||
"Hostname did not resolve to any addresses", | ||
), | ||
} | ||
.into()) |
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.
Actually, this code duplication isn't really necessary. Since async-std
and smol
both use async-io
, the async-std
block should work for both with a few tweaks. And then the async-global-executor
impl can share the same code path as well (async-net
just wraps async-io
).
The difference between async_std::net::ToSocketAddrs
and smol::net::resolve()
seems significant, but in fact, they both simply invoke std::net::ToSocketAddrs
in a blocking task:
- Smol via
async-net
: https://docs.rs/async-net/2.0.0/src/async_net/addr.rs.html#150-153 async-std
via a bespoke implementation: https://docs.rs/async-std/latest/src/async_std/net/addr.rs.html#217-221
Funnily enough, Tokio does the exact same thing: https://docs.rs/tokio/latest/src/tokio/net/addr.rs.html#219-221
They all also have a fast path for when the hostname can be parsed as an IP address that skips the blocking task.
This would be easy enough to implement ourselves in a single code path using our own spawn_blocking
abstraction. Then only runtime-specific part would be deciding which TcpStream
type to use.
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.
Implemented, but it looks that TLS test are failing after this changed. Do not know why so far, even going back does not help.
The issue is that |
As of This is likely going to be delayed until the 0.9.0 release anyway since a whole new runtime feature is a bit much to add in a point release. |
Next question: if 0.9.0 is a target, will sqlx's MSRV be lifted to +1.81? If yes, then the split between |
After all changes (in |
This PR adds
smol
as a third async executor, to overcomeasync_std
obsolescence.async_std
remains working, but it is replaced withsmol
in CI, to reduce number of run tasks.Adding
smol
is not a breaking change.