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>
impl<'a> BorrowedSender<'a>
Sourcepub fn new_buffer(&self) -> Buffer
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.
Sourcepub fn flush(&mut self, chunk: &mut Chunk<'_>) -> Result<()>
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.
Sourcepub fn flush_buffer(&mut self, buffer: &mut Buffer) -> Result<()>
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.
Sourcepub fn flush_buffer_and_keep(&mut self, buffer: &Buffer) -> Result<()>
pub fn flush_buffer_and_keep(&mut self, buffer: &Buffer) -> Result<()>
Publish a caller-owned QWP/WebSocket Buffer without clearing it.
Sourcepub fn flush_buffer_and_get_fsn(
&mut self,
buffer: &mut Buffer,
) -> Result<Option<u64>>
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.
Sourcepub fn flush_buffer_and_keep_and_get_fsn(
&mut self,
buffer: &Buffer,
) -> Result<Option<u64>>
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.
Sourcepub fn flush_buffer_and_wait(
&mut self,
buffer: &mut Buffer,
ack_level: AckLevel,
) -> Result<()>
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.
Sourcepub fn flush_and_wait(
&mut self,
chunk: &mut Chunk<'_>,
ack_level: AckLevel,
) -> Result<()>
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_level — Self::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.
Sourcepub fn flush_and_get_fsn(
&mut self,
chunk: &mut Chunk<'_>,
) -> Result<Option<u64>>
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.
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
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.
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 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.
Sourcepub fn wait(&mut self, ack_level: AckLevel, timeout: Duration) -> Result<()>
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.
Sourcepub fn drop_on_return(&mut self)
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.
Sourcepub fn flush_arrow_batch_at_now<'t, T>(
&mut self,
table: T,
batch: &RecordBatch,
overrides: &[ArrowColumnOverride<'_>],
) -> Result<()>
pub fn flush_arrow_batch_at_now<'t, T>( &mut self, table: T, batch: &RecordBatch, overrides: &[ArrowColumnOverride<'_>], ) -> Result<()>
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.
Sourcepub fn flush_arrow_batch_at_now_and_wait<'t, T>(
&mut self,
table: T,
batch: &RecordBatch,
overrides: &[ArrowColumnOverride<'_>],
ack_level: AckLevel,
) -> Result<()>
pub fn flush_arrow_batch_at_now_and_wait<'t, T>( &mut self, table: T, batch: &RecordBatch, overrides: &[ArrowColumnOverride<'_>], ack_level: AckLevel, ) -> Result<()>
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.
Sourcepub fn flush_arrow_batch_at_now_and_get_fsn<'t, T>(
&mut self,
table: T,
batch: &RecordBatch,
overrides: &[ArrowColumnOverride<'_>],
) -> Result<Option<u64>>
pub fn flush_arrow_batch_at_now_and_get_fsn<'t, T>( &mut self, table: T, batch: &RecordBatch, overrides: &[ArrowColumnOverride<'_>], ) -> Result<Option<u64>>
Arrow counterpart of Self::flush_and_get_fsn, letting the server
stamp each row’s designated timestamp on arrival.
Sourcepub fn flush_arrow_batch_at_column<'t, T>(
&mut self,
table: T,
batch: &RecordBatch,
ts_column: ColumnName<'_>,
overrides: &[ArrowColumnOverride<'_>],
) -> Result<()>
pub fn flush_arrow_batch_at_column<'t, T>( &mut self, table: T, batch: &RecordBatch, ts_column: ColumnName<'_>, overrides: &[ArrowColumnOverride<'_>], ) -> Result<()>
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.
Sourcepub 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<()>
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<()>
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.
Sourcepub 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>>
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>>
Arrow counterpart of Self::flush_and_get_fsn, sourcing the
designated timestamp from the named column.
Trait Implementations§
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<'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