pub struct WeirClient<S = DefaultTransport> { /* private fields */ }Expand description
A synchronous blocking client for one connection to the weir daemon.
The type parameter S is the underlying transport. The default is
DefaultTransport — a Unix domain socket on Unix. When the tls feature
is enabled, S can also be TlsStream (TCP + mutual TLS).
The underlying stream runs in blocking mode. Each method sends one request
frame and reads one response frame before returning. Requests are not
pipelined; for concurrent producers, create one WeirClient per thread.
Drop the client to close the connection. The daemon treats EOF as a clean disconnect.
Implementations§
Source§impl<S: Read + Write> WeirClient<S>
impl<S: Read + Write> WeirClient<S>
Sourcepub fn set_default_durability(&mut self, durability: Durability)
pub fn set_default_durability(&mut self, durability: Durability)
Sets the default durability tier used by push_default.
Sourcepub fn push(
&mut self,
payload: impl AsRef<[u8]>,
durability: Durability,
) -> Result<(), ClientError>
pub fn push( &mut self, payload: impl AsRef<[u8]>, durability: Durability, ) -> Result<(), ClientError>
Pushes payload to the daemon with the given durability tier.
Blocks until the daemon replies. On Ack the record is durably stored
according to the requested tier. On Nack returns the reason as
ClientError::Nack.
An Ack means the record is durably buffered at the requested tier —
not that it has reached the downstream sink yet (the daemon drains in
batches once a segment seals). See the crate-level “Ack vs. delivery” note.
The ack is per record, not a liveness probe for the next one. If the
daemon dies (or the socket is severed) between two pushes, the first
push after the failure can still return Ok — its frame was written and
acked, or the breakage isn’t observed until the next read/write — and only
the following push surfaces the broken pipe. So a single Ok does not
guarantee the connection is healthy for subsequent pushes. After any push
error, branch on ClientError::is_recoverable /
is_poisoned to decide whether to keep using this
client or drop and reconnect, rather than assuming a prior Ok proved the
connection good.
Sourcepub fn push_default(
&mut self,
payload: impl AsRef<[u8]>,
) -> Result<(), ClientError>
pub fn push_default( &mut self, payload: impl AsRef<[u8]>, ) -> Result<(), ClientError>
Pushes at the connection’s default durability tier.
Returns ClientError::NoDefaultDurability if no default was set via
set_default_durability (or via a
connect_with_default / connect_tls constructor that accepted a
default_durability).
Sourcepub fn health_check(&mut self) -> Result<(), ClientError>
pub fn health_check(&mut self) -> Result<(), ClientError>
Sends a HealthCheck frame and returns Ok(()) on a valid
HealthCheckResponse. Returns an error if the daemon is unreachable
or responds with a Nack.
Sourcepub fn is_poisoned(&self) -> bool
pub fn is_poisoned(&self) -> bool
Whether this client’s connection is dead and must be rebuilt.
Reports the union of the two ways a connection becomes unusable, so it is the
exact complement of is_recoverable for the
error that caused it:
- an indeterminate stream (the internal
poisonedflag) — a response-read failure/timeout, a protocol violation in the reply, or any stream desync (an unexpected daemon message type, an empty-payload Nack); leftover/unexpected bytes could be mis-read as a later reply (a false ack); - a connection-closing Nack (the internal
closed_after_nackflag) — every Nack reason except the transientInternalError, after which the daemon closes the connection.
In either state every method fails fast (it will not touch the socket again); the caller must drop this client and open a fresh connection.
A long-lived producer thread (e.g. one driven from an async runtime) should
check this after a failed call — or, equivalently, branch on
ClientError::is_recoverable — and rebuild the connection when it reports
poisoned / non-recoverable, rather than retrying on the dead client:
if let Err(e) = client.push(b"record", Durability::Durable) {
if !e.is_recoverable() || client.is_poisoned() {
client = reconnect(); // drop the dead client, rebuild
}
}See ClientError::is_recoverable for the per-error view of the same
distinction (recoverable = connection still usable; non-recoverable = drop
and reconnect). The two are kept equivalent: is_poisoned() is true after a
failed call exactly when that call’s error is non-recoverable.
Source§impl WeirClient<UnixStream>
impl WeirClient<UnixStream>
Sourcepub fn connect(path: impl AsRef<Path>) -> Result<Self, ClientError>
pub fn connect(path: impl AsRef<Path>) -> Result<Self, ClientError>
Opens a connection to the weir daemon’s Unix socket at path.
Sourcepub fn connect_with_default(
path: impl AsRef<Path>,
durability: Durability,
) -> Result<Self, ClientError>
pub fn connect_with_default( path: impl AsRef<Path>, durability: Durability, ) -> Result<Self, ClientError>
Opens a connection and sets a default durability tier in one step.
Equivalent to calling connect then
set_default_durability.
Sourcepub fn from_stream(stream: UnixStream) -> Self
pub fn from_stream(stream: UnixStream) -> Self
Wraps an already-connected UnixStream. Useful for callers that
manage their own connection setup (systemd socket activation,
pre-authenticated file descriptors passed from a parent process,
UnixStream::pair-based test harnesses).
Sourcepub fn set_read_timeout(&self, timeout: Option<Duration>) -> Result<()>
pub fn set_read_timeout(&self, timeout: Option<Duration>) -> Result<()>
Sets the read timeout on the underlying socket. None (the default)
blocks indefinitely.
Opt-in availability guard. By default every method blocks in the
response-read path (inside push /
health_check) waiting for the daemon’s Ack/Nack, so a
wedged daemon (hung flusher, SIGSTOP, half-open connection) would block
a producer’s hot path forever. With a read timeout set, a stalled reply
surfaces as a ClientError::Io timeout instead; the producer can retry
— the record may still have been durably written, which the at-least-once
contract covers. Pick a value comfortably above the daemon’s Durable ack
latency under load: the daemon’s own ACK_TIMEOUT is 30 s, so e.g.
45–60 s lets the daemon’s Nack win rather than racing it.
Sourcepub fn set_write_timeout(&self, timeout: Option<Duration>) -> Result<()>
pub fn set_write_timeout(&self, timeout: Option<Duration>) -> Result<()>
Sets the write timeout on the underlying socket. None (the default)
blocks indefinitely. See set_read_timeout for
the rationale — this bounds a stalled write_all of the request frame.
Source§impl WeirClient<TlsStream>
impl WeirClient<TlsStream>
Sourcepub fn connect_tls(
addr: impl ToSocketAddrs,
cfg: ClientTlsConfig<'_>,
) -> Result<Self, ClientError>
pub fn connect_tls( addr: impl ToSocketAddrs, cfg: ClientTlsConfig<'_>, ) -> Result<Self, ClientError>
Connects to a weir daemon’s TCP+mTLS listener at addr.
Performs a full mutual-TLS handshake: the client presents client_cert
(signed by the same CA the server trusts), and the server certificate is
validated against ca_cert. The server_name must match a SAN in the
server’s certificate.
Sourcepub fn set_read_timeout(&self, timeout: Option<Duration>) -> Result<()>
pub fn set_read_timeout(&self, timeout: Option<Duration>) -> Result<()>
Sets the read timeout on the underlying TCP socket. None (the default)
blocks indefinitely. Same opt-in availability rationale as the Unix
client’s set_read_timeout — a wedged
daemon would otherwise block a producer forever in read_response.
Sourcepub fn set_write_timeout(&self, timeout: Option<Duration>) -> Result<()>
pub fn set_write_timeout(&self, timeout: Option<Duration>) -> Result<()>
Sets the write timeout on the underlying TCP socket. None (the default)
blocks indefinitely. See set_read_timeout.