execution_trace.bend

bendvy-ecs-core@0.1.0.1 · 80 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.1/change_tick.bend as Tick
3import bendvy-ecs-core@0.1.0.1/trace_facts.bend as Facts
4
5# Detached copied facts. No World, registration, cursor or stream owner is held.
6# Copied system identity for presentation: namespace/id and optional name.
7# It is metadata, not a registration owner or capability for invoking that system.
8type Identity is Data:
9  Identity{namespace:U32,id:U32,name:Maybe<&2,String>}
10# Completion status of one executed system, retaining its detached Data error.
11type Status<Error:Data> is Data:
12  SystemOk{}
13  SystemError{error:Error}
14# Schedule-level completion distinguishes failure, admission rejection and missing
15# execution from success; it is not a replacement for the retained App run result.
16type Completion<Error:Data> is Data:
17  EndOk{}
18  EndFailed{error:Error}
19  EndRejected{}
20  EndMissing{}
21# Ordered copied execution facts: schedule/phase boundaries, systems, operations
22# and admission outcomes. Facts describe the actual run; they grant no mutable
23# World access and do not imply that a failed transaction committed its operations.
24type TraceEvent<Error:Data> is Data:
25  ScheduleStarted{namespace:U32,name:String}
26  PhaseEntered{name:String}
27  SystemCompleted{identity:Identity,before:Tick.Tick,after:Tick.Tick,status:Status<Error>}
28  OperationObserved{identity:Identity,fact:Facts.Fact}
29  BarrierOperationObserved{fact:Facts.Fact}
30  ExecutionOperationObserved{fact:Facts.Fact}
31  SystemSkipped{id:U32}
32  DeferredApplied{}
33  ScheduleEnded{outcome:Completion<Error>}
34  ScheduleAdmissionRefused{namespace:U32,name:String,outcome:Completion<Error>}
35# Detached delivery value returned after execution. Disabled differs from an
36# enabled Ready batch with no events. No live reader or stream retention is held;
37# keeping or dropping a copied batch does not acknowledge an ECS event reader.
38type Batch<Error:Data> is Data:
39  Disabled{}
40  BendvyReady{events:List<&2,TraceEvent<Error>>}
41
42# Each subscription is its actual affine state owner, not a copied callback.
43# The erased reusable step is supplied as a top-level definition.
44type Subscriber<State:Type,Error:Data,-step:State -> TraceEvent<Error> -> State> is Type:
45  Subscriber{state:State}
46# Wrap the supplied actual State owner with a reusable erased step definition.
47# This creates a local subscriber, not an ECS registration or automatic callback.
48def subscribe(~State:Type,~Error:Data,~step:State -> TraceEvent<Error> -> State,state:State) -> Subscriber<State,Error,step>:
49  Subscriber{state}
50# Consume the subscriber and return its actual State for reuse or explicit
51# disposal. No implicit user cleanup/destructor callback is invoked.
52def unsubscribe(~State:Type,~Error:Data,~step:State -> TraceEvent<Error> -> State,value:Subscriber<State,Error,step>) -> State:
53  match value:
54    case Subscriber{state}:state
55# Replace subscription state and return the displaced actual owner separately.
56# Neither owner is copied or silently restored into ECS storage.
57def reset(~State:Type,~Error:Data,~step:State -> TraceEvent<Error> -> State,value:Subscriber<State,Error,step>,incoming:State) -> Subscriber<State,Error,step> & State:
58  match value:
59    case Subscriber{state}:(Subscriber{incoming},state)
60def delivered(~State:Type,~Error:Data,~step:State -> TraceEvent<Error> -> State,events:List<&2,TraceEvent<Error>>,state:State) -> State:
61  match events:
62    case []:state
63    case event <> rest:delivered(~State,~Error,~step,rest,step(state,event))
64# Thread subscriber State through Ready events in list order; Disabled returns
65# the subscriber unchanged. Delivery is explicitly called after the ECS run.
66# Any external printing/file IO performed by a consumer is outside ECS rollback,
67# not an in-transaction observer. See examples/scheduled-health/application.bend.
68def deliver(~State:Type,~Error:Data,~step:State -> TraceEvent<Error> -> State,value:Subscriber<State,Error,step>,batch:Batch<Error>) -> Subscriber<State,Error,step>:
69  match value batch:
70    case subscriber Disabled{}:subscriber
71    case Subscriber{state} BendvyReady{events}:Subscriber{delivered(~State,~Error,~step,events,state)}
72
73# Generic owner composition has no arity or subscriber-count bound. Order is
74# left then right; each reusable delivery function can itself be another pair.
75# Deliver the same detached batch to two actual owners, left then right, returning
76# both results. Compose this adapter recursively for additional subscribers; this
77# is owner composition, not a global subscription registry.
78def both(~Left:Type,~Right:Type,~Error:Data,~left:Left -> Batch<Error> -> Left,~right:Right -> Batch<Error> -> Right,value:Left & Right,+batch:Batch<Error>) -> Left & Right:
79  match value:
80    case (first,second):(left(first,batch),right(second,batch))