Reactors

The reactors plugin runs live mutations. A live mutation is a stored mutation definition with live true and an optional integer priority. Enable it at open with plugins {reactors {}}. It has no settings. See plugin selection for the open options.

Store live mutations with patch_definition under the mutations kind. After each commit, every live mutation evaluates its query as of that transaction. Their patches commit together as one output transaction, completing a round. When patches write different values to one path, the higher priority wins. Equal priorities fail with Reactor_Conflict. The combined patch must satisfy the scoped schemas of every contributing live mutation. A schema rejection records Schema_Validation and commits no output. A failure keeps the cursor before its source transaction until a live mutation definition changes.

Runtime status

Call status to inspect these fields:

FieldContents
enabledWhether the plugin is enabled
cursorLast processed source transaction
headCurrent database head
pendingWhether processing remains
reactorsLive mutations, each with id, name, priority and sinceTx
failureCurrent failure, with sourceTx, code, reactors and path; absent when no failure stands

When to call sync

Live mutations run automatically after commits. Your write can finish before a live mutation has produced its output. Call sync before a read that depends on that output. For example, a live mutation can add greeted after a person is created. A read immediately after creation can miss greeted. Synchronize the reactors before asserting that result in a test. Applications that can observe the output later can let the runtime continue in the background.

Its options accept only the common maxWait option. Success covers source transactions committed before the call. Later transactions can still have pending rounds. A failed round reports failed and appears in status.

Operations

OperationReturnsSummary
reactors_statusdocumentreactors.status() returns the reactor runtime's owned status document.
reactors_syncnonereactors.sync(options) waits until live mutations processed the commits made before the call.

reactors_status

odin100 B
reactors_status :: proc(
	db: Database,
	allocator := context.allocator,
) -> (
	Document,
	Error,
)

Parameters

ParameterTypeOwnershipDefaultMeaning
dbDatabaseBorrowed for the callRequiredThe reactors owner for this operation. Keep it alive during the call.
allocatormem.AllocatorValuecontext.allocatorAllocator for copied return values and diagnostics. The caller releases them with the same allocator.

Errors

StatusWhen
.Unavailablethe database does not enable the reactors plugin
.Closedthe database is closed
.Out_Of_Memorynative memory is exhausted

Notes

The document describes the cursor, pending work, live mutations and failures: see runtime status.

Examples

Describe the live mutation runtime

odin238 B
sync_options := stardust.parse(`{maxWait {#dur PT5S}}`, .DUST) or_return
defer stardust.close(&sync_options)
stardust.reactors_sync(db, sync_options) or_return
result := stardust.reactors_status(db) or_return
defer stardust.close(&result)
Result / 69 B
{
  "enabled": true,
  "cursor": 4,
  "head": 4,
  "pending": false
}

C exports: stardust_db_plugin_call, stardust_result_take_document, stardust_result_error, stardust_result_release

reactors_sync

odin106 B
reactors_sync :: proc(
	db: Database,
	options: Document = {},
	allocator := context.allocator,
) -> Error

Parameters

ParameterTypeOwnershipDefaultMeaning
dbDatabaseBorrowed for the callRequiredThe reactors owner for this operation. Keep it alive during the call.
optionsDocumentBorrowed for the call{}The borrowed call options, or none. Optional maxWait is a nonnegative native duration, such as {maxWait {#dur PT5S}}. Without it, or with zero, the call checks once.
allocatormem.AllocatorValuecontext.allocatorAllocator for copied return values and diagnostics. The caller releases them with the same allocator.

Errors

StatusWhen
.Invalid_Argumentoptions is not an object, or an option is invalid, duplicated or unsupported
.Failedthe plugin's work failed; status describes the failure
.TimeoutmaxWait passed before the work finished
.Unavailablethe database does not enable the reactors plugin
.Closedthe database is closed

Notes

Database close interrupts an active wait. See when to call sync.

Examples

Wait until live mutations caught up

odin238 B
sync_options := stardust.parse(`{maxWait {#dur PT5S}}`, .DUST) or_return
defer stardust.close(&sync_options)
stardust.reactors_sync(db, sync_options) or_return
result := stardust.reactors_status(db) or_return
defer stardust.close(&result)
Result / 69 B
{
  "enabled": true,
  "cursor": 4,
  "head": 4,
  "pending": false
}

C exports: stardust_db_plugin_call, stardust_result_take_document, stardust_result_error, stardust_result_release