docs(console): clarify API and persistence boundaries
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
//! Bounded, asynchronous persistence for data-plane invocation telemetry.
|
||||
//!
|
||||
//! Invocation responses must not wait for libSQL, so producers use
|
||||
//! [`tokio::sync::mpsc::Sender::try_send`] and one task writes ordered batches.
|
||||
//! When the queue is full or closed, the update is deliberately dropped and a
|
||||
//! warning is emitted. These counters and events are operational telemetry;
|
||||
//! they are not suitable as a billing ledger or audit log.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -10,6 +16,10 @@ const QUEUE_CAPACITY: usize = 1024;
|
||||
const MAX_BATCH_SIZE: usize = 64;
|
||||
|
||||
/// Non-blocking producer used by Wasmtime invocation threads.
|
||||
///
|
||||
/// All producers share one FIFO queue. Queue order is preserved for accepted
|
||||
/// records, but a process crash can lose records that have not yet reached
|
||||
/// libSQL.
|
||||
pub(crate) struct InvocationPersistence {
|
||||
sender: mpsc::Sender<Command>,
|
||||
}
|
||||
@@ -21,6 +31,10 @@ enum Command {
|
||||
|
||||
impl InvocationPersistence {
|
||||
/// Starts the single ordered writer on the current Tokio runtime.
|
||||
///
|
||||
/// `sync` is shared with full Console snapshot persistence. Taking it
|
||||
/// around each batch prevents a snapshot transaction from racing a metric
|
||||
/// delta transaction.
|
||||
pub(crate) fn start(persistence: Persistence, sync: Arc<Mutex<()>>) -> Self {
|
||||
let (sender, mut receiver) = mpsc::channel(QUEUE_CAPACITY);
|
||||
tokio::spawn(async move {
|
||||
@@ -45,6 +59,10 @@ impl InvocationPersistence {
|
||||
tracing::error!(%error, "failed to persist invocation telemetry");
|
||||
}
|
||||
}
|
||||
// Flush is an ordering barrier, not a durability receipt. A
|
||||
// database error above is logged rather than returned, and a
|
||||
// flush may wait for records dequeued after the marker when
|
||||
// those records fit in the same batch.
|
||||
for flush in flushes {
|
||||
let _ = flush.send(());
|
||||
}
|
||||
@@ -54,6 +72,9 @@ impl InvocationPersistence {
|
||||
}
|
||||
|
||||
/// Enqueues telemetry without extending API response latency.
|
||||
///
|
||||
/// Saturation drops this update instead of applying backpressure to the
|
||||
/// Component invocation path.
|
||||
pub(crate) fn record(&self, update: InvocationUpdate) {
|
||||
if let Err(error) = self.sender.try_send(Command::Record(update)) {
|
||||
tracing::warn!(%error, "invocation telemetry queue is unavailable; update dropped");
|
||||
@@ -61,6 +82,10 @@ impl InvocationPersistence {
|
||||
}
|
||||
|
||||
/// Waits until all telemetry queued before this call has been attempted.
|
||||
///
|
||||
/// This method is used before a control-plane snapshot so the snapshot
|
||||
/// reads the newest in-memory counters after older delta writes. It does
|
||||
/// not report persistence failures; those are visible through tracing.
|
||||
pub(crate) async fn flush(&self) {
|
||||
let (sender, receiver) = oneshot::channel();
|
||||
if self.sender.send(Command::Flush(sender)).await.is_ok() {
|
||||
|
||||
Reference in New Issue
Block a user