Help us shape the future of Go! Take the 2026 Go Developer Survey

hub

package
v0.136.0 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package hub is the engine's search and signal planes for one tenant: keyword search and typeahead, and the ClickHouse signal plane. The discovery routes and the engine's jobs use it; hosts reach it only through ContentKit's API.

Index

Constants

View Source
const PreferenceEventID = "current"

PreferenceEventID is the stable signal identity of a subject's current preference on one axis: (tenant, canonical reference, subject, axis, "current"). A newer revision supersedes the previous one; a re-send carries the same revision and converges.

Variables

View Source
var (
	// ErrSignalPlaneDisabled is returned by signal methods while the hub has
	// no signal plane: none is configured, or it is down (ErrSignalPlaneDown).
	ErrSignalPlaneDisabled = errors.New("contentkit: signal plane disabled")
	// ErrSignalPlaneDown: the configured signal plane is unreachable until
	// SetSignals opens it again.
	ErrSignalPlaneDown = fmt.Errorf("%w: ClickHouse is down", ErrSignalPlaneDisabled)
)

Functions

This section is empty.

Types

type Client

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

Client answers keyword search and typeahead for one tenant.

func NewClient

func NewClient(cfg ClientConfig) (*Client, error)

func (*Client) KeywordMatch added in v0.126.0

func (c *Client) KeywordMatch(ctx context.Context, userText string, opts SearchOptions) (search.Match, error)

KeywordMatch selects matching (content_id, content_version_id) pairs in the languages opts selects; see search.KeywordMatch. opts.Limit, Offset, CandidateLimit and Eligibility are ignored.

func (*Client) Search

func (c *Client) Search(ctx context.Context, userText string, opts SearchOptions) (SearchResult, error)

Search returns one page of content items. Documents from every searched language are grouped per work before Offset and Limit apply; each hit carries the matched document's reference and language.

func (*Client) Tenant

func (c *Client) Tenant() string

Tenant returns the tenant this client is scoped to.

func (*Client) Typeahead

func (c *Client) Typeahead(ctx context.Context, userText string, opts TypeaheadOptions) ([]TypeaheadHit, error)

Typeahead returns literal title/alias substrings while a user is typing, biased toward exact names and prefixes, one per content item before Limit. Common English fillers are ignored; contextual matching belongs to Search.

type ClientConfig

type ClientConfig struct {
	Pool   *pgxpool.Pool
	Schema string
	// Tenant scopes every document, query and result. Required.
	Tenant string

	// Defaults.
	DefaultLanguage string
	DefaultLimit    int
}

ClientConfig configures the keyword search client of one tenant.

type Config

type Config struct {
	// Content plane (Postgres). PG + PGSchema (ContentKit's schema) are required.
	PG       *pgxpool.Pool
	PGSchema string

	DefaultLanguage string

	// SignalPlane: a signal plane is configured that SetSignals opens later;
	// until then signal methods return ErrSignalPlaneDown. Without it signal
	// methods return ErrSignalPlaneDisabled.
	SignalPlane bool

	// Tenant is the single tenant of this embedded hub. Required: every
	// document, signal, cursor and result carries it.
	Tenant string
}

Config configures one tenant's hub.

type ContentKey

type ContentKey = contentref.ContentKey

ContentKey is the comparable form of a ContentRef.

type ContentRef

type ContentRef = contentref.ContentRef

ContentRef is the tenant-scoped reference to a content item or one of its versions. See contentref.

type Eligibility

type Eligibility = search.Eligibility

Eligibility is the per-document visibility join; see search.Eligibility.

type Hub

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

Hub is one tenant's search client and signal plane: the engine's internal surface the discovery routes build on.

func New

func New(cfg Config) (*Hub, error)

New builds the hub of one tenant.

func (*Hub) Activity added in v0.85.0

func (h *Hub) Activity(ctx context.Context, contentKind string, window signal.Window, cohorts ...signal.ActivityCohort) ([]signal.DayActivity, error)

Activity is a content kind's distinct measured readership per day of window.

func (*Hub) AnonymizeSubject added in v0.117.0

func (h *Hub) AnonymizeSubject(ctx context.Context, old, anonymous signal.Subject) error

AnonymizeSubject preserves anonymous engagement while unlinking an account.

func (*Hub) CompletedCount added in v0.104.0

func (h *Hub) CompletedCount(ctx context.Context, subject signal.Subject, kind string) (int64, error)

func (*Hub) Content

func (h *Hub) Content(contentKind, contentID string) ContentRef

Content returns a reference to a work of this hub's tenant.

func (*Hub) DailyPopular added in v0.131.0

func (h *Hub) DailyPopular(ctx context.Context, kind string, window signal.Window, scope signal.ActivityScope, limit int) ([]signal.PopularHit, error)

func (*Hub) DailyPopularityCoverage added in v0.131.0

func (h *Hub) DailyPopularityCoverage(ctx context.Context, kind string, scope signal.ActivityScope) (signal.Window, bool, error)

func (*Hub) Forget

func (h *Hub) Forget(ctx context.Context, subject signal.Subject, contentKind, contentID string) error

Forget erases the subject's signals for one work and its versions (contentID set) or a whole content kind (contentID empty) — host "clear my history" support.

func (*Hub) ForgetContents added in v0.104.0

func (h *Hub) ForgetContents(ctx context.Context, contents []signal.ForgottenContent) error

ForgetContents erases purged content's signals for every subject.

func (*Hub) History

func (h *Hub) History(ctx context.Context, subject signal.Subject, opts signal.HistoryOptions) ([]signal.StateRow, error)

func (*Hub) ImportLegacyReading added in v0.104.0

func (h *Hub) ImportLegacyReading(ctx context.Context, in []signal.LegacyReading) error

func (*Hub) KeywordMatch added in v0.126.0

func (h *Hub) KeywordMatch(ctx context.Context, userText string, opts SearchOptions) (search.Match, error)

KeywordMatch is the SQL selecting every content item matching userText; see Client.KeywordMatch.

func (*Hub) PopulationCoverage added in v0.98.0

func (h *Hub) PopulationCoverage(ctx context.Context, kind string, scope signal.ActivityScope, window signal.Window) (time.Time, bool, error)

PopulationCoverage is the earliest trusted eligible-audience observation in this app/kind/domain/language and requested activity window.

func (*Hub) PrepareDailyPopularity added in v0.131.0

func (h *Hub) PrepareDailyPopularity(ctx context.Context, kind string, availability signal.Availability, scope signal.ActivityScope, rebuild bool) (signal.DailyPopularityPreparation, error)

PrepareDailyPopularity is explicit worker/admin preparation, not a request cache or background loop. Closed daily aggregates are reused unless rebuilt.

func (*Hub) RecordExposures

func (h *Hub) RecordExposures(ctx context.Context, exposures []signal.Exposure) error

RecordExposures logs one row per result list and stage (served, rendered, visible) so clicks can be attributed to what was actually exposed. Hosts call it once per list per stage, never per item.

func (*Hub) RecordSignals

func (h *Hub) RecordSignals(ctx context.Context, signals []signal.Signal) error

RecordSignals records the batch (see signal.Store.RecordSignals).

func (*Hub) Search

func (h *Hub) Search(ctx context.Context, userText string, opts HubSearchOptions) (SearchResult, error)

func (*Hub) SeenIDs

func (h *Hub) SeenIDs(ctx context.Context, subject signal.Subject, contentKind string) (map[string]struct{}, error)

SeenIDs returns the subject's seen-set for one content kind (the signal-plane half of an unseen anti-join).

func (*Hub) SendPreferences

func (h *Hub) SendPreferences(ctx context.Context, page []content.Preference) error

SendPreferences writes one page into the signal plane: one event per subject × reference × axis with the row's revision, change time and value (0 = neutral / unfavorited). Erased subjects are dropped by the store. It is content's PreferenceSender.

func (*Hub) SetSignals added in v0.86.0

func (h *Hub) SetSignals(s *signalstore.Store)

SetSignals opens the configured signal plane over s, or takes it down (nil) while ClickHouse is unreachable.

func (*Hub) SignalPlane

func (h *Hub) SignalPlane() bool

SignalPlane reports whether the hub's signal plane is up.

func (*Hub) Signals

func (h *Hub) Signals() *signalstore.Store

Signals is the signal plane's store; nil while there is none up.

func (*Hub) SignalsConfigured added in v0.86.0

func (h *Hub) SignalsConfigured() bool

SignalsConfigured reports whether the hub has a signal plane, up or down.

func (*Hub) States

func (h *Hub) States(ctx context.Context, subject signal.Subject, refs []ContentRef) (map[ContentKey]signal.State, error)

func (*Hub) Typeahead

func (h *Hub) Typeahead(ctx context.Context, userText string, opts TypeaheadOptions) ([]TypeaheadHit, error)

type HubSearchOptions

type HubSearchOptions struct {
	SearchOptions
	Personalize *Personalization
}

HubSearchOptions extends content SearchOptions with optional signal-aware personalization.

type LanguageMode

type LanguageMode string
const (
	// LanguageModeExact uses only the requested language.
	LanguageModeExact LanguageMode = "exact"
	// LanguageModeFallbackEnglish uses requested language first, then English.
	LanguageModeFallbackEnglish LanguageMode = "fallback_en"
)

type Personalization

type Personalization struct {
	Subject signal.Subject

	// PopularityWeight is the RRF weight of the candidate-set popularity
	// list blended with the content ranking. Defaults to 0.25.
	PopularityWeight float32
	// Popularity scores candidate works of one kind, higher first; works
	// without a score are absent. Nil leaves popularity out.
	Popularity func(ctx context.Context, kind string, ids []string) (map[string]float64, error)

	// AffinityWeight boosts works the subject already engaged with by
	// (1 + AffinityWeight·last_score/100). 0 = off.
	AffinityWeight float32

	// DemoteSeen demotes already-seen / completed works.
	DemoteSeen bool
	// SeenPenalty multiplies seen-but-not-completed scores (default 0.85).
	SeenPenalty float32
	// CompletedPenalty multiplies completed scores (default 0.6).
	CompletedPenalty float32
	// DislikePenalty multiplies works the subject has net-negative explicit
	// feedback for (default 0.3). Always applied when view context is loaded
	// (i.e. AffinityWeight > 0 or DemoteSeen).
	DislikePenalty float32
}

Personalization fuses signal aggregates into search ranking. Recall is unchanged: a ranking-only layer over the candidate set, which discovery applies for signed-in readers.

type SearchHit

type SearchHit struct {
	// ContentRef names the matched document's content: the work, or the
	// version when the document was indexed per version.
	ContentRef
	// Language is the matched document's language.
	Language string
	// Score ranks the item by its best matching document in any searched
	// language, using the keyword match tier.
	Score float32
}

SearchHit is one content item, represented by its matched document.

type SearchOptions

type SearchOptions struct {
	Language string
	// Defaults to LanguageModeExact when omitted.
	LanguageMode LanguageMode

	// ContentKinds selects the kinds searched. Required.
	ContentKinds []string

	// Limit is the page size in content items; Offset skips items. Documents
	// are grouped per item before either applies.
	Limit  int
	Offset int
	// CandidateLimit is the document window requested from each retrieval
	// source (per language) before grouping. It defaults to twice Offset+Limit
	// (at least 100) and is clamped to at least Offset+Limit. Pass the same
	// value on every page when a truncated window must stay identical.
	CandidateLimit int

	// Eligibility keeps the documents the reader may see (the discovery
	// routes' visibility join); without it every document is eligible.
	Eligibility *Eligibility
}

type SearchResult

type SearchResult struct {
	Hits []SearchHit
	// HasMore is true when items follow this page in the grouped retrieval, or
	// when Truncated: documents beyond the window were never ranked, so the
	// next page may still be non-empty.
	HasMore bool
	// Truncated reports that a candidate window filled. Raise CandidateLimit
	// for complete deep pagination.
	Truncated bool
}

SearchResult is one page of items.

type TypeaheadHit

type TypeaheadHit struct {
	ContentRef
	Language string
	Score    float32
}

TypeaheadHit is one suggested content item and its matched document.

type TypeaheadOptions

type TypeaheadOptions struct {
	Language string
	// Defaults to LanguageModeExact when omitted.
	LanguageMode  LanguageMode
	ContentKinds  []string
	Limit         int
	MinSimilarity float32
	// Eligibility groups suggestions per content item; see SearchOptions.
	Eligibility *Eligibility
	// Source is current management names only for an authorized management
	// caller. The public route always leaves it at PublishedNames.
	Source search.NameSource
}

Jump to

Keyboard shortcuts

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