Skip to main content

Sender

Struct Sender 

Source
pub struct Sender { /* private fields */ }
Expand description

Connects to a QuestDB instance and inserts data via the configured ingestion protocol.

Implementations§

Source§

impl Sender

Source

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.

Source

pub fn connection_events_delivered(&self) -> u64

Total connection events delivered to the listener. 0 when no listener is registered.

Source

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.

Source

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.

Source

pub fn new_buffer(&self) -> Buffer

Creates a new Buffer using the sender’s protocol settings

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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::Ok waits for the server to accept every published frame.
  • AckLevel::Durable waits for durable-ACK coverage. It requires QuestDB Enterprise and a sender opened with request_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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn protocol(&self) -> Protocol

Returns the sender’s configured transport protocol.

Source

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.

Source

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§

Source§

impl Debug for Sender

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

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<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V