writer

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package writer is the single-writer goroutine described in ARCHITECTURE § 7 and § 8. M2 scope: JSONL append only. M3 will extend with SQLite upsert + session inference inside this same goroutine.

Daily rotation per § 7.4: file date is decided by *write time*, not by trace.TsStart. A trace whose ts_start is yesterday but whose finalize happens after midnight lands in today's file. Consumers reconcile via ts_start if they care about request-arrival grouping.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppendResult

type AppendResult struct {
	JSONLPath   string // e.g. "data/2026-05-27/a1b2c3d4.jsonl"
	JSONLOffset int64  // pre-write byte offset where the line starts
	Err         error
}

AppendResult is returned via Record.Reply (if non-nil) after the line is written. M3 uses Offset to populate SQLite's jsonl_offset column.

type Record

type Record struct {
	Trace   trace.Trace
	KeyHash string // 16-hex full key_hash; writer uses KeyHashShort for filename
}

Record is one item on the writer channel. It carries the trace plus a key_hash for file naming. We compute key_hash here (not in the trace struct) because it's not part of the JSONL schema — it's only used by the writer to pick the file, and by M3's SQLite mirror.

type Stats

type Stats struct {
	DropWriterFull int64 // TrySend dropped because channel was full
	DropJSONLFail  int64 // JSONL append failed (disk full, EIO, etc.)
	DropSQLiteFail int64 // SQLite upsert failed (busy timeout, schema err, …)
	Appended       int64 // successful JSONL appends
	Indexed        int64 // successful SQLite upserts (≤ Appended)
}

Stats are the cumulative drop / overflow counters this writer exposes. Will be lifted into a shared Counters package in M4.

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer owns the JSONL writing pipeline. Exactly one goroutine writes to disk; producers send Records on a bounded channel via TrySend.

func New

func New(dataDir string, chanCap int, store *sqlite.Store, ctrs *counters.Counters, mediaExt *media.Extractor, mediaEnabled *atomic.Bool, clock func() time.Time) *Writer

New creates a Writer with the given chan capacity. Call Start to launch its goroutine. Use TrySend to enqueue records. Call the stop fn (from Start) on shutdown to drain the channel and wait for background gzip workers.

store may be nil; tests and pure-JSONL deployments leave it nil. ctrs may be nil; counters skipped if so. clock may be nil; defaults to time.Now.

mediaExt and mediaEnabled (Phase K) may both be nil; either nil means "no extraction." When both are non-nil, the writer reads mediaEnabled on each finalize and, if true, invokes mediaExt.Extract on the trace after the JSONL line is on disk. Extraction failures log WARN inside the extractor and never block the writer or affect MediaCount past the returned slice length (PHILOSOPHY §2: capture never interferes).

func (*Writer) SnapshotStats

func (w *Writer) SnapshotStats() Stats

SnapshotStats returns a copy of the current counters. Safe for concurrent callers (M4's /healthz will use this).

func (*Writer) Start

func (w *Writer) Start() func()

Start launches the writer goroutine. Returns a stop function; calling stop closes the channel and waits for the goroutine to drain it (then waits for background gzip workers). Safe to call stop multiple times; only the first call does work.

func (*Writer) TrySend

func (w *Writer) TrySend(r Record) bool

TrySend non-blockingly enqueues a record. Returns false (and bumps DropWriterFull) if the channel is full. Producers MUST NOT block on the writer per ARCHITECTURE § 7.5 step 3.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL