search

package
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package search provides the optional secondary content-search index. The primary store (db.Store) remains the sole system of record: the index never participates in existence, consolidation, or recall decisions. All index mutations are asynchronous, best-effort, and one-way (primary -> index); the only synchronous call is Search, whose results are always round-tripped through the primary store by the caller.

Index

Constants

This section is empty.

Variables

View Source
var ErrDisabled = errors.New("content search is not enabled (opensearch.enabled is false)")

ErrDisabled is returned by Search when no search index is configured (opensearch.enabled is false).

Functions

This section is empty.

Types

type Config

type Config struct {
	Addresses []string
	Username  string
	Password  string
	Index     string
	QueueSize int

	// Worker tuning. Each is optional: a zero value falls back to the package default
	// (applyTimeout, applyMaxAttempts, applyRetryBaseBackoff, closeDrainTimeout). Raise them for a
	// slower cluster where the defaults drop too many operations before the reconciliation sweep
	// heals them.
	ApplyTimeout          time.Duration
	ApplyMaxAttempts      int
	ApplyRetryBaseBackoff time.Duration
	CloseDrainTimeout     time.Duration

	// TLS carries the optional transport-security settings applied to an https:// cluster.
	TLS TLSConfig

	// Transport overrides the HTTP transport; used by unit tests to fake the cluster. When set it
	// takes precedence over TLS (the fake cluster needs no real transport security).
	Transport http.RoundTripper
}

Config carries the OpenSearch connection settings, read from viper in main.go.

type Doc

type Doc struct {
	Id           string `json:"-"` // becomes the document _id, not a mapped field
	Body         string `json:"body"`
	EventId      string `json:"event_id"`
	Significance int32  `json:"significance"`
	Timestamp    int64  `json:"timestamp"`
	IsSummary    bool   `json:"is_summary"`
	Group        string `json:"group"`
}

Doc is the indexed projection of a memory. Recall state (time_recalled/recall_count) is deliberately excluded: the index never participates in reinforcement decisions, so recalls need no propagation.

func DocFromMemory

func DocFromMemory(in types.Memory) Doc

DocFromMemory maps a memory onto its indexed projection. Callers must not index binary memories (the body is opaque); the write-through hooks enforce that.

type Index

type Index interface {
	// IndexMemory adds or replaces the document for a memory.
	IndexMemory(doc Doc)

	// DeleteMemories removes the documents with the given memory ids.
	DeleteMemories(ids []string)

	// DeleteByEventId removes every document associated with an event.
	DeleteByEventId(eventId string)

	// SetEventId rewrites the event id on every document currently carrying fromEventId; an
	// empty toEventId detaches them.
	SetEventId(fromEventId string, toEventId string)

	// Purge removes every document.
	Purge()

	// Search returns the ids of memories whose body matches the query text, most relevant
	// first, optionally restricted to a single event and/or group. The caller must fetch the
	// returned ids from the primary store; ids that no longer exist there are stale index
	// entries to be dropped.
	Search(ctx context.Context, query Query) ([]string, error)

	// Enabled reports whether a real index is configured; the no-op implementation returns
	// false.
	Enabled() bool

	// Close drains pending operations and releases resources.
	Close() error
}

Index is the secondary content-search contract. Every mutating method enqueues and returns immediately: it never fails, never blocks the caller, and is applied best-effort - a full queue or an unreachable cluster drops the operation with a warning rather than surfacing an error, since the index is rebuildable and stale entries are harmless (reads are re-verified against the primary store).

func NewNoop

func NewNoop() Index

NewNoop returns the disabled search index.

type OpenSearch

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

OpenSearch is the real search index: a thin client plus a single worker goroutine applying queued mutations in FIFO order. One worker is a correctness property, not a limitation - the delete-then-index pair emitted by ReplaceMemoriesWithSummary, and any create-then-delete pair for the same memory, must never be reordered.

func NewOpenSearch

func NewOpenSearch(cfg Config) (*OpenSearch, error)

NewOpenSearch builds the client, best-effort creates the index, and starts the worker. It fails only on unusable configuration (e.g. a malformed address): an unreachable cluster logs a warning and the service starts anyway, with the worker retrying the index bootstrap before applying operations.

func (*OpenSearch) Close

func (o *OpenSearch) Close() error

Close stops accepting operations and waits for the worker to drain the queue, up to a timeout.

func (*OpenSearch) DeleteByEventId

func (o *OpenSearch) DeleteByEventId(eventId string)

func (*OpenSearch) DeleteMemories

func (o *OpenSearch) DeleteMemories(ids []string)

func (*OpenSearch) Enabled

func (o *OpenSearch) Enabled() bool

func (*OpenSearch) IndexMemory

func (o *OpenSearch) IndexMemory(doc Doc)

func (*OpenSearch) IndexMemorySync

func (o *OpenSearch) IndexMemorySync(ctx context.Context, doc Doc) error

IndexMemorySync indexes one document synchronously, bypassing the queue and returning the error, bounded by the same per-operation timeout the worker uses. It exists for the backfill CLI mode, which needs to know whether each write landed; the service's own write path must keep using IndexMemory (asynchronous, never blocking, FIFO-ordered against deletes).

func (*OpenSearch) Purge

func (o *OpenSearch) Purge()

func (*OpenSearch) RecreateIndex

func (o *OpenSearch) RecreateIndex(ctx context.Context) error

RecreateIndex synchronously deletes and recreates the index, removing every document — including stale entries for memories the primary store no longer has. It backs the --reindex flag of the backfill CLI mode.

func (*OpenSearch) Search

func (o *OpenSearch) Search(ctx context.Context, query Query) ([]string, error)

Search returns the ids of memories whose body matches the query, most relevant first. This is the only synchronous cluster call the service itself makes; the *Sync methods above exist only for the backfill CLI mode.

func (*OpenSearch) SetEventId

func (o *OpenSearch) SetEventId(fromEventId string, toEventId string)

type Query

type Query struct {
	Text    string
	EventId string
	Group   string
	Limit   int
}

Query carries the parameters of one content search. Text is required; EventId and Group restrict matches when non-empty.

type TLSConfig added in v0.7.0

type TLSConfig struct {
	// CACertFile is a PEM bundle of certificate authorities to trust for the server certificate,
	// used in place of the system pool. Set it to trust a cluster serving a certificate signed by
	// a private CA - including the OpenSearch security plugin's self-signed demo certificates.
	CACertFile string

	// CertFile and KeyFile are a client certificate/key pair for mutual TLS. Both must be set
	// together, or neither.
	CertFile string
	KeyFile  string

	// InsecureSkipVerify disables server certificate verification entirely. It is a
	// development-only escape hatch for self-signed certificates - prefer CACertFile in
	// production, where an unverified connection offers no protection against interception.
	InsecureSkipVerify bool
}

TLSConfig carries the optional TLS settings for the OpenSearch connection. Every field is empty/false by default, in which case the client relies on the address scheme alone (an https:// address verifies against the system certificate pool with no customisation), matching the behaviour before this block existed.

Jump to

Keyboard shortcuts

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