Skip to main content

Module writer

Module writer 

Source
Expand description

Bounded, non-blocking background writer for observability persistence (Task 11, spec §6.5).

One cloneable TelemetryWriter handle serves BOTH record kinds:

  • legacy per-request TelemetryRecords → the existing ~/.cache/synaps/api-log.jsonl (format unchanged: one raw JSON object per line, exactly what the old synchronous write_record produced);
  • metadata-only RequestTraces (Tasks 7–10) → a private trace log at ~/.cache/synaps/request-trace.jsonl. Each line is the unwrapped synaps-request-trace/1 object, so any schema-aware reader can parse lines directly.

Design contract:

  • Never blocks the request path. Enqueue is a try_send on a bounded queue; overflow increments a dropped counter (never waits). No awaits, no hidden runtime dependency — the worker is a dedicated OS thread, so sync contexts can enqueue too.
  • Single-owner writes. Only the worker thread touches the files, so size-capped rotation is concurrency-safe by construction.
  • Private files. All paths use the Phase 1 private_fs helpers: parent 0700, file 0600, O_NOFOLLOW (a planted symlink is refused, never followed).
  • Observable, quiet failure. Atomic counters for enqueued/written/dropped/serialization/I-O failures; at most one warning per persistent failure class (queue overflow, serialization, open/write, rotate). Warnings carry a class label only — never record content or paths. The open/write latch re-arms after a successful write so a new persistent failure warns again.
  • Bounded shutdown. TelemetryWriter::shutdown stops intake, drains until the deadline, and returns typed stats. Dropping the last handle simply disconnects the queue: the worker drains what is buffered and exits detached — Drop can never hang.

Production wiring rule (documented until Task 12 adds explicit trace config/UI): telemetry basic/full enables BOTH legacy telemetry persistence and metadata-only trace persistence through this writer; off disables both. The trace schema is structurally metadata-only, so this can never silently persist raw content.

Structs§

TelemetryWriter
Cloneable handle to the bounded background writer.
WriterOptions
Writer configuration. None paths resolve to the installation defaults.
WriterStats
Snapshot of the writer’s atomic counters.
WriterTraceSink
Production TraceSink: enqueues each record onto the shared writer.

Enums§

ShutdownOutcome
Typed result of a bounded shutdown flush.

Constants§

DEFAULT_MAX_FILE_BYTES
Default per-file size cap before rotation (matches the legacy writer).
DEFAULT_QUEUE_CAPACITY
Default bounded queue capacity: deep enough that a briefly slow disk never drops records, small enough to bound memory (records are boxed).
DEFAULT_SHUTDOWN_FLUSH_TIMEOUT
Default budget for the shutdown flush at process-exit epilogues (Task 11): long enough for a healthy disk to drain a full queue, short enough that a hung filesystem can never stall a clean exit.

Functions§

default_telemetry_log_path
Default telemetry log path: ~/.cache/synaps/api-log.jsonl.
default_trace_log_path
Default trace log path: ~/.cache/synaps/request-trace.jsonl.