Skip to main content

BorrowedSender

Struct BorrowedSender 

Source
pub struct BorrowedSender<'a>(/* private fields */);
Expand description

Store-and-forward QWP sender borrowed from a QuestDb pool — the handle returned by QuestDb::borrow_sender.

Self::flush appends a frame to the connection’s store-and-forward queue and returns as soon as it is accepted locally (no server round-trip); the connection’s background runner delivers it asynchronously. While the handle is borrowed or parked in the pool the runner keeps delivering, so returning or dropping the handle does not by itself lose accepted frames.

Delivery is completed best-effort when the pool is closed or the connection is retired, bounded by close_flush_timeout (default 5s): an in-memory queue whose server stays unreachable past that window drops its undelivered tail, logging a warning. For a hard guarantee, call Self::wait before closing the pool — it blocks until the frames published so far reach the requested AckLevel, i.e. confirms delivery — or configure sf_dir for crash-durable on-disk persistence with replay. Self::flush_and_wait combines the two (“publish this batch and return once it is delivered”); its wait is bounded by the pool-wide request_timeout setting, so compose Self::flush then Self::wait if you want to pass an explicit timeout instead. Use FSNs only for non-blocking progress tracking while this borrowed sender is still held: they are stream watermarks, not portable receipts to check through an arbitrary later pool borrow.

Not Send or Sync.

The lease cannot outlive its pool:

use questdb::{BorrowedSender, QuestDb};

fn escape() -> BorrowedSender<'static> {
    let db = QuestDb::connect("ws::addr=localhost:9000;").unwrap();
    db.borrow_sender().unwrap()
}

It cannot be moved to another thread:

use questdb::QuestDb;

let db = QuestDb::connect("ws::addr=localhost:9000;").unwrap();
let sender = db.borrow_sender().unwrap();
std::thread::scope(|scope| {
    scope.spawn(move || drop(sender));
});

Nor can a shared reference be sent to another thread:

use questdb::QuestDb;

let db = QuestDb::connect("ws::addr=localhost:9000;").unwrap();
let sender = db.borrow_sender().unwrap();
std::thread::scope(|scope| {
    scope.spawn(|| std::hint::black_box(&sender));
});

Implementations§

Source§

impl<'a> BorrowedSender<'a>

Source

pub fn new_buffer(&self) -> Buffer

Create a caller-owned QWP/WebSocket Buffer using the pool’s configured name limit. The buffer is not tied to this lease and may be flushed by another sender borrowed from the same pool.

Source

pub fn flush(&mut self, chunk: &mut Chunk<'_>) -> Result<()>

Encode and publish chunk into the store-and-forward queue, returning as soon as the frame is accepted locally (no server round-trip). On success chunk is cleared; on a delivery-uncertain failure the error is tagged in_doubt.

Source

pub fn flush_buffer(&mut self, buffer: &mut Buffer) -> Result<()>

Publish a caller-owned QWP/WebSocket Buffer into this sender’s local store-and-forward queue and clear it after local acceptance.

Source

pub fn flush_buffer_and_keep(&mut self, buffer: &Buffer) -> Result<()>

Publish a caller-owned QWP/WebSocket Buffer without clearing it.

Source

pub fn flush_buffer_and_get_fsn( &mut self, buffer: &mut Buffer, ) -> Result<Option<u64>>

Publish and clear a QWP/WebSocket Buffer, returning its local frame sequence number. Empty buffers publish no frame and return None.

Source

pub fn flush_buffer_and_keep_and_get_fsn( &mut self, buffer: &Buffer, ) -> Result<Option<u64>>

Publish a QWP/WebSocket Buffer without clearing it and return its local frame sequence number. Empty buffers return None.

Source

pub fn flush_buffer_and_wait( &mut self, buffer: &mut Buffer, ack_level: AckLevel, ) -> Result<()>

Publish and clear a QWP/WebSocket Buffer, then wait for the requested ACK boundary using the pool’s configured request timeout.

Source

pub fn flush_and_wait( &mut self, chunk: &mut Chunk<'_>, ack_level: AckLevel, ) -> Result<()>

Publish chunk into the store-and-forward queue as a completion boundary, then wait until every frame published on this handle so far reaches ack_levelSelf::flush followed by Self::wait in one call. Unlike Self::wait, which takes an explicit timeout argument, this call’s wait is bounded by the pool-wide request_timeout setting (the no-progress timeout fires when the ack watermark stops advancing for that long); compose the two calls yourself to choose the timeout per call.

AckLevel::Durable requires QuestDB Enterprise and a pool opened with request_durable_ack=on; otherwise the call is rejected up front (InvalidApiCall) before chunk is touched.

Failure contract: if local publication fails, chunk is untouched and retryable. Once the frame is accepted into the queue chunk is cleared even if the wait then fails. On the no-progress timeout (ErrorCode::FailoverRetry) the frames remain queued and the background runner keeps delivering them — recover by calling Self::wait until it returns Ok, not by re-flushing (which would deliver the same rows twice). A terminal server rejection or transport failure instead ends delivery on this sender: drop the borrow and recover per the rejection policy.

Source

pub fn flush_and_get_fsn( &mut self, chunk: &mut Chunk<'_>, ) -> Result<Option<u64>>

Encode and publish chunk into the store-and-forward queue and return the highest published frame sequence number.

This is the non-blocking progress-tracking form of Self::flush: success means the frame was accepted locally, not that the server has ACKed it. If the chunk is split into multiple frames, the returned FSN is the final frame boundary; cumulative ACK coverage of that boundary covers the whole chunk. Use Self::wait when you only need a simple blocking barrier for everything published so far. Treat the returned FSN as meaningful only with this sender stream while this borrow is held.

Source

pub fn published_fsn(&self) -> Result<Option<u64>>

Return the highest frame sequence number published locally by this sender, or None if no frame has been published.

This is a stream watermark for the currently borrowed sender, not a portable receipt to check through an arbitrary later pool borrow.

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 Enterprise durable-ACK mode this watermark advances after durable ACK coverage; use Self::wait when you need an explicit AckLevel::Ok or AckLevel::Durable barrier. Compare it only with FSNs produced by this same sender stream.

Source

pub fn wait(&mut self, ack_level: AckLevel, timeout: Duration) -> Result<()>

Wait up to timeout for every frame published through this lease so far to reach ack_level. Short-circuits when the lease published nothing or the watermark already covers its latest frame. The barrier is a watermark check plus a terminal-latch check: only a terminal connection failure fails it. Server rejections are delivered to the pool’s rejection handler (default: logged; see QuestDb::connect_with_handlers) rather than raised here; retriable ones are replayed by the queue. AckLevel::Durable requires QuestDB Enterprise and a pool opened with request_durable_ack=on.

timeout is a no-progress deadline (it fires only if the ack watermark fails to advance for that long); Duration::ZERO waits indefinitely. On expiry it returns an ErrorCode::FailoverRetry error; the frames remain queued and the background runner keeps delivering them, so recover by calling wait() again until it returns Ok — not by re-flushing, which would deliver the same rows twice.

Source

pub fn drop_on_return(&mut self)

Force this borrowed connection to be dropped (not recycled) on return.

Use normal Drop for healthy connections: the return path already retires connections that latched terminal state, or whose pool has been closed. Call this after abandoning work or handling an error where the next borrower must not inherit this backend. If queued store-and-forward frames must not be lost, call Self::wait first or configure sf_dir for replay.

Source

pub fn flush_arrow_batch_at_now<'t, T>( &mut self, table: T, batch: &RecordBatch, overrides: &[ArrowColumnOverride<'_>], ) -> Result<()>
where T: TryInto<TableName<'t>>, Error: From<T::Error>,

Encode and publish an Arrow RecordBatch into the queue, letting the server stamp each row’s designated timestamp on arrival. Publish-only; call Self::wait for an ack.

Source

pub fn flush_arrow_batch_at_now_and_wait<'t, T>( &mut self, table: T, batch: &RecordBatch, overrides: &[ArrowColumnOverride<'_>], ack_level: AckLevel, ) -> Result<()>
where T: TryInto<TableName<'t>>, Error: From<T::Error>,

ACKing counterpart of Self::flush_arrow_batch_at_now: publish the batch as a completion boundary, then wait for ack_level. The same contract as Self::flush_and_wait applies.

Source

pub fn flush_arrow_batch_at_now_and_get_fsn<'t, T>( &mut self, table: T, batch: &RecordBatch, overrides: &[ArrowColumnOverride<'_>], ) -> Result<Option<u64>>
where T: TryInto<TableName<'t>>, Error: From<T::Error>,

Arrow counterpart of Self::flush_and_get_fsn, letting the server stamp each row’s designated timestamp on arrival.

Source

pub fn flush_arrow_batch_at_column<'t, T>( &mut self, table: T, batch: &RecordBatch, ts_column: ColumnName<'_>, overrides: &[ArrowColumnOverride<'_>], ) -> Result<()>
where T: TryInto<TableName<'t>>, Error: From<T::Error>,

Encode and publish an Arrow RecordBatch into the queue, sourcing the designated timestamp from the named column. Publish-only; call Self::wait for an ack.

Source

pub fn flush_arrow_batch_at_column_and_wait<'t, T>( &mut self, table: T, batch: &RecordBatch, ts_column: ColumnName<'_>, overrides: &[ArrowColumnOverride<'_>], ack_level: AckLevel, ) -> Result<()>
where T: TryInto<TableName<'t>>, Error: From<T::Error>,

ACKing counterpart of Self::flush_arrow_batch_at_column: publish the batch as a completion boundary, then wait for ack_level. The same contract as Self::flush_and_wait applies.

Source

pub fn flush_arrow_batch_at_column_and_get_fsn<'t, T>( &mut self, table: T, batch: &RecordBatch, ts_column: ColumnName<'_>, overrides: &[ArrowColumnOverride<'_>], ) -> Result<Option<u64>>
where T: TryInto<TableName<'t>>, Error: From<T::Error>,

Arrow counterpart of Self::flush_and_get_fsn, sourcing the designated timestamp from the named column.

Trait Implementations§

Source§

impl Debug for BorrowedSender<'_>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for BorrowedSender<'a>

§

impl<'a> !Send for BorrowedSender<'a>

§

impl<'a> !Sync for BorrowedSender<'a>

§

impl<'a> !UnwindSafe for BorrowedSender<'a>

§

impl<'a> Freeze for BorrowedSender<'a>

§

impl<'a> Unpin for BorrowedSender<'a>

§

impl<'a> UnsafeUnpin for BorrowedSender<'a>

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