-
-
Notifications
You must be signed in to change notification settings - Fork 1
402. Inspecting a run
When Run() returns, the error tells you why the mesh stopped — the run-time report tells you what happened: how many cycles ran, which components activated in each cycle, and with what outcome. This page shows how to read it.
Run() returns (*RuntimeInfo, error). The report is populated even when Run() returns an error.
| Field / method | Description |
|---|---|
Cycles *cycle.Group |
Ordered history of activation cycles |
StartedAt, StoppedAt
|
Wall-clock timestamps |
Duration() |
Total execution time |
ri, err := fm.Run()
if err != nil {
log.Printf("mesh stopped: %v (ran %d cycles in %v)", err, ri.Cycles.Len(), ri.Duration())
}
for _, cyc := range ri.Cycles.All() {
fmt.Printf("Cycle #%d: %d activations, errors=%v\n",
cyc.Number(),
cyc.ActivationResults().Len(),
cyc.HasActivationErrors(),
)
}Two things bound what the history contains:
-
CyclesHistoryLimit(config, default unlimited) capsCyclesto a sliding window of the most recent cycles — older cycles are evicted. Set it for long runs; see Tips & tricks. -
Idle components are not recorded. A cycle's
ActivationResults()only contains results for components that had at least one input signal that cycle. A missingByName(name)entry means "component had no input that cycle" — treat anilresult the same as not-activated.
Each entry in RuntimeInfo.Cycles is a cycle.Cycle:
| Method | Description |
|---|---|
Number() |
1-based sequence number |
ActivationResults() |
Per-component results for this cycle |
HasActivationErrors() / HasActivationPanics()
|
Status checks |
HasActivatedComponents() |
At least one component activated |
AllErrorsCombined() / AllPanicsCombined()
|
Joined errors from all components |
RuntimeInfo.Cycles is a group with the same API as signal and port groups (All, First, Last, Find, Filter, ForEach, …) — see Collections and Groups.
Each component activation produces an ActivationResult. Query it with ComponentName(), Activated(), Code(), ActivationError(), IsError(), IsPanic(). The per-cycle collection supports ByName, All, Filter, ForEach, Every, Any, Count, and FindAny.
| Code | Meaning |
|---|---|
ActivationCodeOK |
Success |
ActivationCodeNoInput |
Not activated — no input signals (never recorded in cycle history; you only see it from MaybeActivate, below) |
ActivationCodeReturnedError |
Activation function returned an error |
ActivationCodePanicked |
Panic during activation (recovered with stack trace — a component panic never crashes the mesh) |
ActivationCodeWaitingForInputsClear |
Waiting; inputs were cleared |
ActivationCodeWaitingForInputsKeep |
Waiting; inputs kept for the next cycle |
ActivationCodeHookFailed |
A component hook failed |
Helpers: component.IsWaitingForInput(result), component.WantsToKeepInputs(result).
Match with errors.Is:
| Error | When |
|---|---|
ErrReachedMaxAllowedCycles |
CyclesLimit exceeded |
ErrTimeLimitExceeded |
TimeLimit exceeded |
ErrHitAnErrorOrPanic |
Error/panic with StopOnFirstErrorOrPanic
|
ErrHitAPanic |
Panic with StopOnFirstPanic
|
ErrFailedToDrain |
Signal draining failed |
ErrUnsupportedErrorHandlingStrategy |
Invalid strategy |
Natural completion returns nil.
You don't need to validate anything yourself:
-
AddComponentsrejects invalid components immediately (e.g. missing activation function). - Every
Run()starts by validating the mesh structure (pipe directions, all pipe destinations belonging to the same mesh) and fails fast with a deterministic error if something is miswired.
MaybeActivate() runs a single activation outside a full mesh run — handy in unit tests:
_ = myComponent.InputByName("in").PutPayloads(42)
result := myComponent.MaybeActivate()
// result.Code() == component.ActivationCodeOK