pub struct Sender { /* private fields */ }Expand description
Connects to a QuestDB instance and inserts data via the configured ingestion protocol.
- To construct an instance, use
Sender::from_confor theSenderBuilder. - To prepare messages, use
Bufferobjects. - To send messages, call the
flushmethod.
Implementations§
Source§impl Sender
impl Sender
Sourcepub fn connection_events_dropped(&self) -> u64
pub fn connection_events_dropped(&self) -> u64
Total connection events discarded by the listener inbox’s
drop-oldest policy. 0 when no listener is registered.
Sourcepub fn connection_events_delivered(&self) -> u64
pub fn connection_events_delivered(&self) -> u64
Total connection events delivered to the listener. 0 when no
listener is registered.
Sourcepub fn from_conf<T: AsRef<str>>(conf: T) -> Result<Self>
pub fn from_conf<T: AsRef<str>>(conf: T) -> Result<Self>
Create a new Sender instance from the given configuration string.
The format of the string is: "http::addr=host:port;key=value;...;".
Instead of "http", you can also specify "https", "tcp", "tcps",
and "udp".
We recommend HTTP for most cases because it provides more features, like reporting errors to the client and supporting transaction control. TCP can sometimes be faster in higher-latency networks, but misses a number of features.
Keys in the config string correspond to same-named methods on SenderBuilder.
For the full list of keys and values, see the docs on SenderBuilder.
You can also load the configuration from an environment variable.
See Sender::from_env.
In the case of TCP, this synchronously establishes the TCP connection, and returns once the connection is fully established. If the connection requires authentication or TLS, these will also be completed before returning.
Sourcepub fn from_env() -> Result<Self>
pub fn from_env() -> Result<Self>
Create a new Sender from the configuration stored in the QDB_CLIENT_CONF
environment variable. The format is the same as that accepted by
Sender::from_conf.
In the case of TCP, this synchronously establishes the TCP connection, and returns once the connection is fully established. If the connection requires authentication or TLS, these will also be completed before returning.
Sourcepub fn new_buffer(&self) -> Buffer
pub fn new_buffer(&self) -> Buffer
Creates a new Buffer using the sender’s protocol settings
Sourcepub fn flush_and_keep_with_flags(
&mut self,
buf: &Buffer,
transactional: bool,
) -> Result<()>
pub fn flush_and_keep_with_flags( &mut self, buf: &Buffer, transactional: bool, ) -> Result<()>
Send the batch of rows in the buffer to the QuestDB server, and, if the
transactional parameter is true, ensure the flush will be transactional.
A flush is transactional iff all the rows belong to the same table. This allows QuestDB to treat the flush as a single database transaction, because it doesn’t support transactions spanning multiple tables. Additionally, only ILP-over-HTTP supports transactional flushes; QWP/UDP is a best-effort datagram transport and has no flush-level atomicity guarantee.
If the flush wouldn’t be transactional, this function returns an error and doesn’t flush any data.
The function sends an HTTP request and waits for the response. If the server responds with an error, it returns a descriptive error. In the case of a network error, it retries until it has exhausted the retry time budget.
All the data stays in the buffer. Clear the buffer before starting a new batch.
Sourcepub fn flush_and_keep(&mut self, buf: &Buffer) -> Result<()>
pub fn flush_and_keep(&mut self, buf: &Buffer) -> Result<()>
Send the given buffer of rows to the QuestDB server.
All the data stays in the buffer. Clear the buffer before starting a new batch.
To send and clear in one step, call Sender::flush instead.
Sourcepub fn flush(&mut self, buf: &mut Buffer) -> Result<()>
pub fn flush(&mut self, buf: &mut Buffer) -> Result<()>
Send the given buffer of rows to the QuestDB server, clearing the buffer.
After this function returns, the buffer is empty and ready for the next batch. If you want to preserve the buffer contents, call Sender::flush_and_keep. If you want to ensure the flush is transactional, call Sender::flush_and_keep_with_flags.
With ILP-over-HTTP, this function sends an HTTP request and waits for the response. If the server responds with an error, it returns a descriptive error. In the case of a network error, it retries until it has exhausted the retry time budget.
With ILP-over-TCP, the function blocks only until the buffer is flushed to the underlying OS-level network socket, without waiting to actually send it to the server. In the case of an error, the server will quietly disconnect: consult the server logs for error messages.
With QWP-over-UDP, the function sends one or more UDP datagrams and returns local socket errors only. A successful return does not guarantee delivery, and when a flush spans multiple datagrams there is no all-or-nothing guarantee for the logical batch.
With QWP-over-WebSocket, the function publishes the rows into local
memory or Store-and-Forward storage and returns without waiting for the
submitted frame’s server ACK. It may still wait for local capacity. In
the default background progress mode, a sender-owned runner sends,
receives ACKs, reconnects, and replays as needed. In manual progress
mode, the caller must use Sender::drive_once or
Sender::wait to advance WebSocket progress. Server or
transport failures observed later are reported by subsequent sender
calls.
HTTP should be the first choice, but use TCP if you need to continuously send data to the server at a high rate.
To improve the HTTP performance, send larger buffers (with more rows), and consider parallelizing writes using multiple senders from multiple threads.
Sourcepub fn flush_and_get_fsn(&mut self, buf: &mut Buffer) -> Result<Option<u64>>
pub fn flush_and_get_fsn(&mut self, buf: &mut Buffer) -> Result<Option<u64>>
Publish the QWP/WebSocket buffer and return the highest published frame sequence number.
This is QWP/WebSocket-specific. It has the same local-publication
semantics as Sender::flush: it returns after the frame is accepted
by the local replay queue, before the server necessarily ACKs it. Empty
buffers return Ok(None).
Use this when you need non-blocking/pipelined progress tracking on this
sender stream: keep the returned FSN and compare it with
Self::acked_fsn. Use Self::wait instead when you only need a
blocking barrier for everything published so far.
Sourcepub fn flush_and_keep_and_get_fsn(
&mut self,
buf: &Buffer,
) -> Result<Option<u64>>
pub fn flush_and_keep_and_get_fsn( &mut self, buf: &Buffer, ) -> Result<Option<u64>>
Publish the QWP/WebSocket buffer without clearing it and return the highest published frame sequence number.
The returned FSN has the same local-publication semantics as
Self::flush_and_get_fsn.
Sourcepub fn published_fsn(&self) -> Result<Option<u64>>
pub fn published_fsn(&self) -> Result<Option<u64>>
Return the highest frame sequence number published locally by this
QWP/WebSocket sender, or None if no frame has been published.
This is a sender-stream watermark, not a process-global receipt.
Sourcepub fn acked_fsn(&self) -> Result<Option<u64>>
pub fn acked_fsn(&self) -> Result<Option<u64>>
Return the highest frame sequence number completed by server ACK or
server-side reject-and-continue, or None if no frame has completed.
In QWP/WebSocket durable ACK mode, ordinary OK frames do not advance
this watermark; it advances once durable ACKs cover the frame.
After Self::flush_and_get_fsn returns Some(fsn), that publication
boundary has completed once this method returns a value greater than or
equal to fsn. Use Self::wait when you need an explicit
AckLevel::Ok or AckLevel::Durable barrier.
Sourcepub fn wait(&mut self, ack_level: AckLevel, timeout: Duration) -> Result<()>
pub fn wait(&mut self, ack_level: AckLevel, timeout: Duration) -> Result<()>
Wait until every QWP/WebSocket frame published so far on this sender
reaches ack_level, or until the wait makes no progress for timeout.
This is the row-major counterpart to the column-major
crate::BorrowedSender::wait: it takes the cumulative publication
boundary (Self::published_fsn) and blocks until the requested
completion watermark covers it.
AckLevel::Okwaits for the server to accept every published frame.AckLevel::Durablewaits for durable-ACK coverage. It requires QuestDB Enterprise and a sender opened withrequest_durable_ack=on; otherwise the call is rejected before checking whether any frame has been published.
timeout is a no-progress deadline: it fires only if the ack
watermark fails to advance for that long, so a steadily-progressing
large batch keeps waiting. Duration::ZERO waits indefinitely. On
expiry it returns an
ErrorCode::FailoverRetry
error and the published frames are retained for replay.
A terminal server rejection of a frame in the pending range, or a
terminal transport/protocol failure, is returned as an error. Retriable
server rejections reconnect and replay until the frame is acknowledged or
the sender is stopped. When nothing has been published yet, a valid wait
returns immediately. QWP/WebSocket only; other
protocols return InvalidApiCall. In manual progress mode this also
drives WebSocket progress while waiting.
Sourcepub fn poll_qwp_ws_error(&mut self) -> Result<Option<QwpWsSenderError>>
pub fn poll_qwp_ws_error(&mut self) -> Result<Option<QwpWsSenderError>>
Poll the next structured QWP/WebSocket server error observed by this sender.
This reports QWP server non-OK responses and WebSocket protocol violations. It remains usable after the sender has halted so callers can inspect the error that made it terminal.
Sourcepub fn qwp_ws_errors_dropped(&self) -> Result<u64>
pub fn qwp_ws_errors_dropped(&self) -> Result<u64>
Return how many QWP/WebSocket structured diagnostics were dropped because the sender’s unified bounded diagnostic log was full.
The same log feeds Sender::poll_qwp_ws_error and
QwpWsErrorHandler notification delivery through independent cursors.
A diagnostic is retained until both cursors have consumed it, so a
lagging cursor can cause later diagnostics to overwrite unread entries
and increment this count.
Sourcepub fn qwp_ws_totals(&self) -> Result<QwpWsTotals>
pub fn qwp_ws_totals(&self) -> Result<QwpWsTotals>
Snapshot the QWP/WebSocket sender’s lifetime totals.
Mirrors the getTotal* counters on Java’s QwpWebSocketSender so the
QuestDB Enterprise e2e harness (questdb-ent/e2e) can read identical
signals across language bindings. See QwpWsTotals for the field
list. Returns InvalidApiCall for non-QWP/WebSocket senders.
Sourcepub fn drive_once(&mut self) -> Result<bool>
pub fn drive_once(&mut self) -> Result<bool>
Drive one QWP/WebSocket progress step when the sender was built with
QwpWsProgress::Manual.
One call performs, in order:
- send at most one queued frame;
- drain all ready response frames from the transport (acks, durable acks, rejects), applying their effects on local store state;
- perform at most one bounded storage-maintenance step (provision a missing hot spare or trim one fully-acked sealed segment) when Store-and-Forward is configured;
- send a durable-ACK keepalive only if nothing above produced progress and one is due.
Returns Ok(true) if any of those steps produced progress and
Ok(false) when the call was idle. Manual schedulers should keep
calling drive_once until it returns false before parking, since the
receive drain and storage maintenance are paced one unit per call:
hot-spare provisioning and segment trim each take their own call, so a
large ACK can free segment-cap headroom over several drive_once
turns.
Sourcepub fn close_drain(&mut self) -> Result<()>
pub fn close_drain(&mut self) -> Result<()>
Stop accepting new QWP/WebSocket publications and wait for all already published frames to complete.
The wait is bounded by the QWP/WebSocket close_flush_timeout_millis
setting. Its default is 5000 ms, matching the Java sender. Values less
than or equal to zero skip the wait.
Sourcepub fn must_close(&self) -> bool
pub fn must_close(&self) -> bool
Tell whether the sender is no longer usable and must be dropped.
Returns true after an unrecoverable failure. For ILP-over-TCP this
is any socket error. For QWP/WebSocket this also covers a server
rejection or protocol violation that latches the publication
lifecycle to its terminal state. ILP-over-HTTP and QWP/UDP never
transition into a permanently-unusable state and always return
false.
In QWP/WebSocket manual progress mode the answer only refreshes when
the user drives the sender (drive_once / flush), since no
background thread is observing the transport.
Sourcepub fn protocol_version(&self) -> ProtocolVersion
pub fn protocol_version(&self) -> ProtocolVersion
Returns the sender’s protocol version.
The returned value may be explicitly configured, auto-detected, or a
transport-defined default. Interpret it together with Sender::protocol
and ProtocolVersion. For QWP/UDP this reports the QWP datagram
version, currently represented as ProtocolVersion::V1; it is not an
ILP feature version.
Sourcepub fn max_name_len(&self) -> usize
pub fn max_name_len(&self) -> usize
Return the sender’s maxinum name length of any column or table name.
This is either set explicitly when constructing the sender,
or the default value of 127.
When unset and using protocol version 2 over HTTP, the value is read
from the server from the cairo.max.file.name.length setting in
server.conf which defaults to 127.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Sender
impl !Sync for Sender
impl !UnwindSafe for Sender
impl Freeze for Sender
impl Send for Sender
impl Unpin for Sender
impl UnsafeUnpin for Sender
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
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 more