computed

package
v1.3.0 Latest Latest
Warning

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

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

Documentation

Overview

Package computed materializes read-only computed attributes. A computed attribute's value is derived (a formula over the entity's other values) and stored like any value by an event subscriber, so it is queryable in FQL with no special-casing. Writing one through the values API is rejected; only this materializer (an internal write) sets it.

The subscriber recomputes on any value change to the entity and converges: re-setting an unchanged computed value emits no event, so the recompute loop terminates.

A schema change to a computed attribute also rebuilds the affected type's entities, off the request goroutine, so a corrected formula converges without waiting for each entity to be written again.

Rollup aggregates over relationships are NOT implemented, and a rollup definition is refused at create/update rather than accepted — see domain/attribute/computed.go. An accepted rollup would have produced an attribute that the schema advertises and that never holds a value.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EventTypes

func EventTypes() []events.Type

EventTypes lists the events the materializer subscribes to: value changes drive a recompute, and definition changes invalidate the per-type "has computed attributes" cache (a formula attribute added to or removed from a type — or any of its ancestors — changes whether its entities need recomputing).

Types

type Materializer

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

Materializer recomputes an entity's computed attributes when its values change, writing the results as (internal) values.

func NewMaterializer

func NewMaterializer(factory application.Factory) *Materializer

NewMaterializer builds the computed-attribute subscriber.

func (*Materializer) Handle

func (m *Materializer) Handle(ctx context.Context, env events.Envelope) error

Handle implements events.Handler. A definition event invalidates the cache; a value event recomputes the one entity it names.

func (*Materializer) HandleBatch added in v1.1.0

func (m *Materializer) HandleBatch(ctx context.Context, envs []events.Envelope) error

HandleBatch implements events.BatchHandler. It coalesces one commit's value events per (tenant, type, entity) so each touched entity is recomputed once, not once per value event: a row that sets ten attributes emits ten events but needs a single recompute. A definition event anywhere in the batch flushes the cache first, so a recompute later in the same commit sees the fresh schema.

func (*Materializer) Name

func (m *Materializer) Name() string

Name implements events.Handler.

func (*Materializer) OnFormulaError added in v1.3.0

func (m *Materializer) OnFormulaError(fn func(err error))

OnFormulaError registers the callback invoked when a stored formula cannot be parsed. The facade wires it to the background-error observer.

func (*Materializer) OnSchemaChange added in v1.3.0

func (m *Materializer) OnSchemaChange(fn func(tenant valueobjects.TenantID, typeID string))

OnSchemaChange registers the callback invoked when a schema change may have invalidated materialized values. It is not safe to call once the materializer is dispatching; wire it during composition.

func (*Materializer) Recompute

func (m *Materializer) Recompute(ctx context.Context, typeID, entityID string) error

Recompute evaluates every computed formula attribute of the entity's type and materializes the results. Missing inputs (or division by zero) remove a stale computed value rather than writing a wrong one.

func (*Materializer) RecomputeTenant added in v1.1.0

func (m *Materializer) RecomputeTenant(ctx context.Context, tenant valueobjects.TenantID) (int, error)

RecomputeTenant re-materializes every entity's computed attributes for a tenant — the recovery counterpart to the search index's Reindex. Internal projections are maintained in the originating request's post-commit (issue #211), so read-your-writes holds regardless of the outbox setting; the trade-off is that a process crash between commit and that post-commit can leave a computed value stale. Running this rebuilds them all. It pages types and their entities, skipping types with no computed attributes, and reuses the per-entity Recompute (each in its own unit of work). Pagination stays correct even though Recompute bumps an entity's last_updated_at: each page's cursor is taken from the values read before that page was recomputed, so a recomputed entity moves ahead of the cursor and is never revisited.

func (*Materializer) RecomputeType added in v1.3.0

func (m *Materializer) RecomputeType(ctx context.Context, tenant valueobjects.TenantID, typeID string) (int, error)

RecomputeType rebuilds every entity of one type, and of its subtypes, since an inherited computed attribute belongs to those too. It returns the number of entities recomputed.

Jump to

Keyboard shortcuts

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