Weave
Reference for Weave scheduling, callback model, dependencies, and health surfaces.
Weave is Aether's periodic execution primitive for control, synchronization, and simulation logic.
Construction
Create Weaves after Nexus and Sigils are declared, and before nexus.start().
Key parameters:
label: stable loop name used for introspection, logs, and tracing.cycle_time: period in seconds between callback runs.callback: async or sync callable executed each cycle.depends_on: optional list of dependency Weaves awaited via their completion events before the callback runs.description: optional operator-facing summary.
Execution model
- Weaves are soft real-time loops.
- A Weave transitions from
PENDINGtoRUNNINGwhen Nexus starts weave execution. - Each cycle runs the callback (async or sync), tracks cycle timing, and updates status.
- If execution misses timing budgets, status can move to
FAILEDorOVERRUN.
Dependency behavior
- Before a callback run, a Weave awaits all
depends_oncompletion events. - This is event-based cycle synchronization, not a hard real-time scheduler guarantee.
- Use dependencies to express ordering intent (for example: estimator before controller), then validate timing under realistic load.
Runtime surfaces
Each Weave registers REST and MCP read surfaces automatically.
REST endpoints (by weave id):
GET /weave/{id}-> labelGET /weave/{id}/description-> descriptionGET /weave/{id}/cycle_time-> cycle timeGET /weave/{id}/cycles-> completed cycle countGET /weave/{id}/next_cycle-> next scheduled cycle time
MCP endpoint:
- Read-only structured tool named from
Weave {label} status - Returns
WeaveInfofields:label,description,status,cycle_time,next_cycle,cycles
Interaction with Sigils
A common pattern:
- Read writable command Sigils (
setpoint,mode, thresholds). - Read measured or simulated state Sigils.
- Compute one control/simulation step.
- Write outputs back to target Sigils.
This keeps operational surfaces (OPC UA/REST/MCP) and internal loop state aligned around the same Sigil values.
Minimal example
from aether.nexus import Nexus
from aether.sigil import Sigil
from aether.weave import Weave
nexus = Nexus(opc_ua_url="opc.tcp://localhost:4840")
setpoint = Sigil(node_id="ns=2;s=Loop.Setpoint", initial_value=25.0)
measurement = Sigil(node_id="ns=2;s=Loop.Measurement", initial_value=20.0, writable=False)
async def first_order_step():
sp = float(await setpoint.read())
pv = float(await measurement.read())
pv += (sp - pv) * 0.02
await measurement.write(pv)
Weave(
label="loop_step",
cycle_time=0.1,
callback=first_order_step,
description="Simple first-order process update.",
)
if __name__ == "__main__":
nexus.start()