dependency_executor.bend
bendvy-ecs-core@0.1.0.3 · 58 lines · 10 definitions
1import Base
2import bendvy-ecs-core@0.1.0.3/dependency_plan.bend as Plan
3
4type Condition<Error:Data> is Data:
5 Allowed{}
6 Disabled{}
7 ConditionError{error:Error}
8 ConditionRefused{}
9type Invocation<Error:Data,Out:Data> is Data:
10 Completed{output:Out}
11 BodyError{error:Error,output:Out}
12 AdmissionRefused{}
13type Handling is Data:
14 Continue{}
15 Escalate{}
16type Observation<Error:Data,Out:Data> is Data:
17 Ran{id:U32,output:Out}
18 BodyFailed{id:U32,error:Error,output:Out}
19 Skipped{id:U32}
20 ConditionFailed{id:U32,error:Error}
21 ConditionRejected{id:U32}
22 AdmissionRejected{id:U32}
23type ExecutionResult<State:Type,Requirement:Data,Error:Data,Out:Data> is Type:
24 Finished{state:State,events:List<&2,Observation<Error,Out>>}
25 Stopped{state:State,error:Error,events:List<&2,Observation<Error,Out>>}
26 Invalid{state:State,reason:Plan.Invalid<Requirement>}
27
28def handled(~State:Type,~Requirement:Data,~Error:Data,~Out:Data,next:State -> List<&2,Observation<Error,Out>> -> ExecutionResult<State,Requirement,Error,Out>,returned:State & Handling,error:Error,events:List<&2,Observation<Error,Out>>) -> ExecutionResult<State,Requirement,Error,Out>:
29 match returned:
30 case (state,Continue{}):next(state,events)
31 case (state,Escalate{}):Stopped{state,error,events}
32
33def invoked(~State:Type,~Requirement:Data,~Error:Data,~Out:Data,~handler:State -> Error -> State & Handling,next:State -> List<&2,Observation<Error,Out>> -> ExecutionResult<State,Requirement,Error,Out>,returned:State & Invocation<Error,Out>,+id:U32,events:List<&2,Observation<Error,Out>>) -> ExecutionResult<State,Requirement,Error,Out>:
34 match returned:
35 case (state,Completed{output}):next(state,List.append(&2,Observation<Error,Out>,events,[Ran{id,output}]))
36 case (state,BodyError{+error,output}):handled(~State,~Requirement,~Error,~Out,next,handler(state,error),error,List.append(&2,Observation<Error,Out>,events,[BodyFailed{id,error,output}]))
37 case (state,AdmissionRefused{}):next(state,List.append(&2,Observation<Error,Out>,events,[AdmissionRejected{id}]))
38
39def conditioned(~State:Type,~Requirement:Data,~Error:Data,~Out:Data,~dispatch:State -> U32 -> State & Invocation<Error,Out>,~handler:State -> Error -> State & Handling,next:State -> List<&2,Observation<Error,Out>> -> ExecutionResult<State,Requirement,Error,Out>,returned:State & Condition<Error>,+id:U32,events:List<&2,Observation<Error,Out>>) -> ExecutionResult<State,Requirement,Error,Out>:
40 match returned:
41 case (state,Allowed{}):invoked(~State,~Requirement,~Error,~Out,~handler,next,dispatch(state,id),id,events)
42 case (state,Disabled{}):next(state,List.append(&2,Observation<Error,Out>,events,[Skipped{id}]))
43 case (state,ConditionError{+error}):handled(~State,~Requirement,~Error,~Out,next,handler(state,error),error,List.append(&2,Observation<Error,Out>,events,[ConditionFailed{id,error}]))
44 case (state,ConditionRefused{}):next(state,List.append(&2,Observation<Error,Out>,events,[ConditionRejected{id}]))
45
46def execute(~State:Type,~Requirement:Data,~Error:Data,~Out:Data,~condition:State -> U32 -> State & Condition<Error>,~dispatch:State -> U32 -> State & Invocation<Error,Out>,~handler:State -> Error -> State & Handling,order:List<&2,Plan.Node<Requirement>>,state:State,events:List<&2,Observation<Error,Out>>) -> ExecutionResult<State,Requirement,Error,Out>:
47 match order:
48 case []:Finished{state,events}
49 case Plan.Node{+id,_} <> rest:conditioned(~State,~Requirement,~Error,~Out,~dispatch,~handler,state => events => execute(~State,~Requirement,~Error,~Out,~condition,~dispatch,~handler,rest,state,events),condition(state,id),id,events)
50
51
52
53
54
55def run(~State:Type,~Requirement:Data,~Error:Data,~Out:Data,~condition:State -> U32 -> State & Condition<Error>,~dispatch:State -> U32 -> State & Invocation<Error,Out>,~handler:State -> Error -> State & Handling,plan:Plan.Build<Requirement>,state:State) -> ExecutionResult<State,Requirement,Error,Out>:
56 match plan:
57 case Plan.Rejected{reason}:Invalid{state,reason}
58 case Plan.Planned{order,_}:execute(~State,~Requirement,~Error,~Out,~condition,~dispatch,~handler,order,state,[])