Documentation
¶
Overview ¶
Package embedworker is the production span-embedding loop: it runs the bounded span-embedding pass (see pkg/spanembed) on its own interval, in its own process (`tapes serve embed-worker`) — split out of the derive worker so that embedding NEVER blocks derivation.
Why a separate process: embedding calls an external provider (OpenAI, Ollama) whose latency and availability are outside Tapes' control. As an inline step of the derive loop it could not fail or hang without stalling the projection of raw turns into the read model. Here it has its own memory budget, its own failure domain, and its own replica count; derivation is untouched whatever the embedding backend does.
The pass is idempotent and keyed by span identity, so running it on a timer — and running multiple replicas — only costs redundant reads. A per-span embed failure (the provider rejected the input or was unreachable for that span) is counted and logged but never aborts the pass; the span stays un-embedded and the next run retries it.
Index ¶
Constants ¶
const ( DefaultInterval = time.Minute DefaultMaxBackoff = 5 * time.Minute DefaultDrainTimeout = 30 * time.Second )
Defaults for Config fields left zero.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Interval is how often a full embed pass runs. A pass also runs
// once immediately at startup to clear the standing backlog.
Interval time.Duration
// MaxBackoff caps the jittered exponential backoff applied between
// passes while the pass keeps failing on infrastructure (database or
// embedding backend unreachable), so an outage costs one line per
// retry at a widening cadence instead of hammering a dead backend
// every Interval.
MaxBackoff time.Duration
// DrainTimeout bounds graceful shutdown: after the run context is
// canceled, an in-flight pass may keep running this long before its
// store/backend calls are aborted.
DrainTimeout time.Duration
// Ready optionally backs the readiness probe. Nil reports ready as
// soon as the worker exists.
Ready ReadyFunc
// Metrics optionally injects a pre-built metrics surface so the
// hosting command can mount /metrics before the store is reachable.
// NewWorker builds a fresh one when nil.
Metrics *Metrics
}
Config tunes the worker loop. Zero fields take the package defaults.
type Metrics ¶
type Metrics struct {
// Passes counts embed passes by outcome: ok / error (an
// infrastructure failure — candidate listing or prune — that aborted
// the pass; per-span failures are not pass failures).
Passes *prometheus.CounterVec
// PassDuration is the wall time of one full pass.
PassDuration prometheus.Histogram
// Per-span outcomes accumulated across passes. Together they close the
// identity scanned = embedded + upToDate + empty + poisoned + failed,
// so a dashboard can both account for every candidate and SEE the
// re-stream cost: the embed pass lists and renders every main llm
// span each pass, so a high upToDate (or scanned) with embedded≈0 is
// the wasteful-rescan signature, invisible if only embedded/failed
// were exposed. Failed is a per-span embed/write error retried next
// pass; UpToDate skipped because content+model already match; Empty
// skipped because the delta rendered to no embeddable text; Poisoned
// skipped because the span already failed deterministically under this
// content and model.
SpansScanned prometheus.Counter
SpansEmbedded prometheus.Counter
SpansUpToDate prometheus.Counter
SpansEmpty prometheus.Counter
SpansPoisoned prometheus.Counter
SpansFailed prometheus.Counter
// SpansChunked counts spans whose text exceeded the model context
// window and was embedded as several pieces; ChunkRows counts the
// pieces written (so chunked spans contribute more than one row).
SpansChunked prometheus.Counter
ChunkRows prometheus.Counter
// Oversize counts spans the model rejected as too large; OversizeTokens
// is the distribution of their reported/estimated token sizes — the
// answer to "how big are the inputs we're chunking?".
Oversize prometheus.Counter
OversizeTokens prometheus.Histogram
// SpanFailures counts deterministic per-span failures by reason (e.g.
// oversize, api_400) — the recorded, non-retried failures, a subset of
// SpansFailed broken out for alerting on a specific cause.
SpanFailures *prometheus.CounterVec
// OrphansPruned counts embedding rows removed because their span no
// longer exists as a main llm span.
OrphansPruned prometheus.Counter
// ConsecutiveFailures mirrors the worker's in-memory outage counter:
// non-zero means passes are currently failing on infrastructure and
// backing off. Alert on sustained non-zero.
ConsecutiveFailures prometheus.Gauge
// LastSuccessTimestamp is the Unix time of the last successful pass.
// Alert on staleness (time() - metric > interval): it catches a
// wedged-but-not-erroring worker, which ConsecutiveFailures cannot.
LastSuccessTimestamp prometheus.Gauge
// contains filtered or unexported fields
}
Metrics is the Prometheus surface for the embed worker. Each worker owns its own registry so tests scrape in isolation and the hosting command mounts Handler on its listener.
func NewMetrics ¶
func NewMetrics() *Metrics
NewMetrics constructs the embed worker's counters on a fresh registry.
func (*Metrics) Registry ¶
func (m *Metrics) Registry() *prometheus.Registry
Registry exposes the registry so tests can scrape it.
type Pass ¶
Pass runs one bounded span-embedding pass and reports what it did. *spanembed.Pass satisfies it; tests substitute a fake.
type ReadyFunc ¶
ReadyFunc reports whether the worker's dependencies are reachable — the /readyz signal. Typically a database ping. Nil means always ready (the process is up).
type Worker ¶
type Worker struct {
// contains filtered or unexported fields
}
Worker owns the startup-pass / interval / drain loop.
func (*Worker) Metrics ¶
Metrics exposes the worker's Prometheus surface so the hosting command can mount a scrape endpoint.
func (*Worker) Ready ¶
Ready reports whether the worker can do useful work right now. With no ReadyFunc configured it reports ready once the worker exists.
func (*Worker) Run ¶
Run blocks until ctx is canceled. One pass runs immediately at startup (clearing the standing backlog), then the interval timer takes over.
Shutdown is graceful: canceling ctx stops scheduling new passes, but an in-flight pass keeps running on a detached context for up to DrainTimeout before its calls are aborted. Run then returns nil.