pub struct PoolClient { /* private fields */ }Expand description
A thin UDS client for communicating with a pool worker process.
Each PoolClient instance owns a single Unix domain socket connection to
one worker. Messages are JSON lines (\n-terminated).
§Lifecycle
- Call
PoolClient::connect— opens the socket and runs the version handshake atomically. If the handshake fails the connection is dropped and an error is returned; noPoolClientinstance is produced. - Call
PoolClient::send_requestfor each message. - Drop the
PoolClientwhen done; the underlying socket is closed.
Implementations§
Source§impl PoolClient
impl PoolClient
Sourcepub async fn connect(sock_path: &Path) -> Result<Self, PoolError>
pub async fn connect(sock_path: &Path) -> Result<Self, PoolError>
Open a connection to a worker at sock_path and verify protocol version.
The handshake (PoolRequest::Handshake) is performed inside this call.
If the worker reports a different version, Err(PoolError::VersionMismatch)
is returned and no PoolClient is constructed.
§Concurrency
Cancel safety: this function is not cancel safe. If dropped before
recv_line completes, the internal BufReader may hold a partial line;
the partial connection is dropped and must not be reused.
Timeout: the handshake recv is bounded by HANDSHAKE_RECV_TIMEOUT
(10 s). If the worker does not respond within this window, the function
returns Err(PoolError::Handshake("handshake recv timeout (10s)")) and the
connection is dropped. This prevents RunningService::cancel from hanging
when a worker fails to send the handshake.
Send + Sync: PoolClient is Send (all fields are Send). It is
not Sync — callers sharing across tasks must wrap in
Arc<tokio::sync::Mutex<PoolClient>>.
§Errors
PoolError::Connect— socket connect failed (wrapsstd::io::Error).PoolError::Handshake— response could not be parsed as valid JSON, or the handshake recv timed out after 10 s.PoolError::VersionMismatch— worker version differs from client version.
Sourcepub async fn send_request(
&mut self,
req: PoolRequest,
) -> Result<PoolResponse, PoolError>
pub async fn send_request( &mut self, req: PoolRequest, ) -> Result<PoolResponse, PoolError>
Send a PoolRequest over the Unix domain socket and await the response.
Serialises the request to a JSON line (\n-terminated), writes it via
tokio::io::AsyncWriteExt::write_all, then reads the response with
tokio::io::AsyncBufReadExt::read_line.
§Concurrency
Cancel safety: this function is not cancel safe.
AsyncBufReadExt::read_line is not cancel safe per tokio documentation:
if this future is dropped before read_line completes, the internal buffer
may hold a partial line. After cancellation the connection is no longer
usable; callers must drop this PoolClient and reconnect.
Mutex serialisation: the internal tokio::sync::Mutex<Inner> serialises
concurrent callers. Cancelling a lock().await call loses queue position
(tokio docs: “Cancelling a call to lock makes you lose your place in the
queue”). Only one request can be in-flight per PoolClient instance at a
time. Holding the guard across .await (write + flush + read_line) is
intentional and correct with tokio::sync::Mutex.
Send + Sync: PoolClient is Send (all fields are Send). It is
not Sync — callers sharing across tasks must wrap in
Arc<tokio::sync::Mutex<PoolClient>>.
§Panics
Does not panic.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for PoolClient
impl !RefUnwindSafe for PoolClient
impl Send for PoolClient
impl Sync for PoolClient
impl Unpin for PoolClient
impl UnsafeUnpin for PoolClient
impl UnwindSafe for PoolClient
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreimpl<T> MaybeSend for Twhere
T: Send,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.