feat: Async 2.0
Async resolving
struct CAresAddrInfo
is a rust mirror of the C struct ares_getaddrinfo
from ares.h
and need to implement an automatic drop logic of the result after it converted to the Rust SocketAddr
. For this conversion we use the additional type struct SocketAddress
.
Memory which using as context of the ares_getaddrinfo
request will also be dropped automatically when GetAddrInfo
future completed.
pub async fn connect() {
...
let sockaddr = SocketAddress::resolve(url, port).await?; ---------.
let stream = std::net::TcpStream::connect(sockaddr) |
.map_err(Error::Connect)?; |
... |
} |
|
struct SocketAddress(*mut CAresAddrInfo, u16); |
impl ToSocketAddrs for SocketAddress {...} |
|
impl Drop for SocketAddress { |
... |
crate::ffi::tarantool::coio_ares_freeaddrinfo(self.0); |
} |
|
impl SocketAddress { |
pub async fn resolve() { <---------------------------------------'
...
let addrinfo = GetAddrInfo::from_url(&host).await?; ------.
... |
} |
} |
|
impl Future for GetAddrInfo { | (calling the future)
fn poll() { |
... |
addrinfo.memory = unsafe { |
crate::ffi::tarantool::coio_ares_getaddrinfo( |
addrinfo.host.as_ptr(), |
&mut addrinfo.result as *mut _, |
addrinfo.err.as_ptr(), |
) |
}; |
... |
return Poll::Ready(Ok(addrinfo.result)); <----------------'
}
}
impl Drop for GetAddrInfo {
fn drop(&mut self) {
unsafe {
crate::ffi::tarantool::coio_ares_request_drop(self.memory);
}
}
}
Async waiting
Wait events installs when the future processed by block_on
calls the set_coio_wait
which push new wait event to event vector stored in ContextExt
. This vector stores the pointer to event memory inside. Then block_on
initialize this pointer by the event memory allocation with coio_wait_event_alloc
.
When some future is ready in block_on
the memory freed with coio_wait_event_free
before Poll::Ready
returns.
Timeout
Now deadline of the timeout
wrapper for the block_on
futures handles via libev timer which links to the fiber it was installed by and awake this fiber in its own callback on the C side.
Known problems
- connect still not async
- seems that timeout implementation can't broke current tests, but can work with only one fiber
- better it would be to implement coio events waiting without using ContextExt at all anyhow