ordinary_app_service.bend
bendvy-ecs-core@0.1.0.4 · 114 lines · 23 definitions
1import Base
2import bendvy-ecs-core@0.1.0.4/change_tick.bend as Tick
3import bendvy-ecs-core@0.1.0.4/capabilities.bend as Cap
4import bendvy-ecs-core@0.1.0.4/ordinary_service_declaration.bend as D
5import bendvy-ecs-core@0.1.0.4/world.bend as W
6import bendvy-ecs-core@0.1.0.4/system.bend as Sys
7import bendvy-ecs-core@0.1.0.4/schedule.bend as Sch
8import bendvy-ecs-core@0.1.0.4/schedule_provision.bend as SP
9import bendvy-ecs-core@0.1.0.4/schema_fragments.bend as Fragment
10
11
12type Application<S:Data,C:Type,R:Type,E:Data,-runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,-scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>> is Type:
13 Application{setup:D.Setup<S,C,R,E,scan>,plan:SP.Plan<S>,scheduled:SP.Provisioned<S,C,R,E,Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>>,world:W.World<S,C,R,E>,debug:Bool}
14
15
16type Installation<App:Type,World:Type,Setup:Data,Owner:Type> is Type:
17 Installed{app:App}
18 InstallRejected{world:World,setup:Setup,owner:Maybe<&1,Owner>}
19
20
21type Inventory<S:Data> is Data:
22 Inventory{entries:List<&2,Fragment.Entry<S>>,services:List<&2,D.Status<S>>,required:List<&2,SP.Requirement<S>>,namespace:U32,id:U32,name:String,access:List<&2,String>,cursor:Maybe<&2,Tick.Tick>,steps:List<&2,Sch.Step>}
23
24
25
26type RunResult<App:Type,S:Data> is Type:
27 Finished{app:App,observations:List<&2,Sch.Observation>}
28 Failed{app:App,error:Unit,observations:List<&2,Sch.Observation>}
29 Rejected{app:App}
30 Missing{app:App,missing:List<&2,SP.Requirement<S>>}
31def built(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,~scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>,setup:D.Setup<S,C,R,E,scan>,plan:SP.Plan<S>,world:W.World<S,C,R,E>,result:SP.Build<S,C,R,E,Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>>) -> Installation<Application<S,C,R,E,runner,scan>,W.World<S,C,R,E>,D.Setup<S,C,R,E,scan>,Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>>:
32 match result:
33 case SP.Invalid{owner}:InstallRejected{world,setup,Some{owner}}
34 case SP.Built{scheduled}:Installed{Application{setup,plan,scheduled,world,False{}}}
35def planned(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,~scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>,setup:D.Setup<S,C,R,E,scan>,world:W.World<S,C,R,E>,owner:Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>,ns:U32,+id:U32,+plan:SP.Plan<S>) -> Installation<Application<S,C,R,E,runner,scan>,W.World<S,C,R,E>,D.Setup<S,C,R,E,scan>,Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>>:
36 built(~S,~C,~R,~E,~runner,~scan,setup,plan,world,SP.build(~S,~C,~R,~E,~Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>,ns,"service-schedule",plan,[id],owner))
37def registered(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,~scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>,setup:D.Setup<S,C,R,E,scan>,requirement:SP.Requirement<S>,result:Sys.RegistrationResult<S,C,R,E,Unit,Unit,Unit,runner>) -> Installation<Application<S,C,R,E,runner,scan>,W.World<S,C,R,E>,D.Setup<S,C,R,E,scan>,Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>>:
38 match result:
39 case Sys.RegistrationFailed{world}:InstallRejected{world,setup,None{}}
40 case Sys.Registered{world,Sys.Registry{+ns,+id,name,access,cursor}}:planned(~S,~C,~R,~E,~runner,~scan,setup,world,Sys.Registry{ns,id,name,access,cursor},ns,id,SP.Sequence{SP.Entry{Sch.Barrier{},[]},SP.Entry{Sch.System{id,0},[requirement]}})
41
42def enabled(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,~scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>,app:Application<S,C,R,E,runner,scan>,flag:Bool) -> Application<S,C,R,E,runner,scan>:
43 match app:
44 case Application{setup,plan,scheduled,world,_}:Application{setup,plan,scheduled,world,flag}
45def described(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,~scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>,setup:D.Setup<S,C,R,E,scan>,plan:SP.Plan<S>,scheduled:SP.Provisioned<S,C,R,E,Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>>,observed:W.World<S,C,R,E> & List<&2,D.Status<S>>) -> Application<S,C,R,E,runner,scan> & Maybe<&2,Inventory<S>>:
46 match setup scheduled observed:
47 case D.Setup{+entries}, SP.Provisioned{Sch.Schedule{+ns,+scheduleName,+steps,Sys.Registry{+registryNs,+id,+name,+access,+cursor}},+needs}, (world,statuses):(Application{D.Setup{entries},plan,SP.Provisioned{Sch.Schedule{ns,scheduleName,steps,Sys.Registry{registryNs,id,name,access,cursor}},needs},world,True{}},Some{Inventory{entries,statuses,needs,registryNs,id,name,access,cursor,steps}})
48
49
50
51def snapshot(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,~scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>,app:Application<S,C,R,E,runner,scan>) -> Application<S,C,R,E,runner,scan> & Maybe<&2,Inventory<S>>:
52 match app:
53 case Application{setup,plan,scheduled,world,False{}}:(Application{setup,plan,scheduled,world,False{}},None{})
54 case Application{setup,plan,scheduled,world,True{}}:described(~S,~C,~R,~E,~runner,~scan,setup,plan,scheduled,scan(world))
55def dispatched(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,value:Sys.RunResult<S,C,R,E,Unit,Unit,Unit,runner>) -> Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner> & Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>:
56 match value:
57 case Sys.Completed{owner,outcome}:(owner,outcome)
58 case Sys.RegistrationRejected{owner,world,_}:(owner,Sys.Failed{world,Unit{}})
59
60
61
62def dispatch(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,owner:Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>,world:W.World<S,C,R,E>,_:U32) -> Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner> & Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>:
63 dispatched(~S,~C,~R,~E,~runner,Sys.run(~S,~C,~R,~E,~Unit,~Unit,~Unit,~runner,owner,world,Unit{}))
64
65def condition(~S:Data,~C:Type,~R:Type,~E:Data,world:W.World<S,C,R,E>,_:U32) -> W.World<S,C,R,E> & Bool:
66 (world,True{})
67def executed(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,~scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>,setup:D.Setup<S,C,R,E,scan>,plan:SP.Plan<S>,debug:Bool,needs:List<&2,SP.Requirement<S>>,value:Sch.RunResult<S,C,R,E,Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>,Unit>) -> RunResult<Application<S,C,R,E,runner,scan>,S>:
68 match value:
69 case Sch.Finished{schedule,world,observations}:Finished{Application{setup,plan,SP.Provisioned{schedule,needs},world,debug},observations}
70 case Sch.Failed{schedule,world,error,observations}:Failed{Application{setup,plan,SP.Provisioned{schedule,needs},world,debug},error,observations}
71 case Sch.Rejected{schedule,world}:Rejected{Application{setup,plan,SP.Provisioned{schedule,needs},world,debug}}
72def provisioned(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,~scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>,setup:D.Setup<S,C,R,E,scan>,plan:SP.Plan<S>,debug:Bool,value:SP.ProvisionResult<S,C,R,E,Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>,Unit>) -> RunResult<Application<S,C,R,E,runner,scan>,S>:
73 match value:
74 case SP.Missing{scheduled,world,missing}:Missing{Application{setup,plan,scheduled,world,debug},missing}
75 case SP.Executed{value,needs}:executed(~S,~C,~R,~E,~runner,~scan,setup,plan,debug,needs,value)
76
77
78
79
80def run(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,~scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>,app:Application<S,C,R,E,runner,scan>) -> RunResult<Application<S,C,R,E,runner,scan>,S>:
81 match app:
82 case Application{setup,plan,scheduled,world,debug}:provisioned(~S,~C,~R,~E,~runner,~scan,setup,plan,debug,SP.run(~S,~C,~R,~E,~Sys.Registry<S,C,R,E,Unit,Unit,Unit,runner>,~Unit,~dispatch(~S,~C,~R,~E,~runner),~condition(~S,~C,~R,~E),~D.provision(~S,~C,~R,~E,~scan),scheduled,world))
83
84
85
86def install(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Rest:Type,~take:R -> Rest & D.Slot<P>,~put:Rest -> D.Slot<P> -> R,~call:P -> P,~declaration:D.Declaration<S,R,P,Rest,take,put,call>,~scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>,setup:D.Setup<S,C,R,E,scan>,world:W.World<S,C,R,E>,name:String) -> Installation<Application<S,C,R,E,D.runner(~S,~C,~R,~E,~P,~Rest,~take,~put,~call,~declaration),scan>,W.World<S,C,R,E>,D.Setup<S,C,R,E,scan>,Sys.Registry<S,C,R,E,Unit,Unit,Unit,D.runner(~S,~C,~R,~E,~P,~Rest,~take,~put,~call,~declaration)>>:
87 registered(~S,~C,~R,~E,~D.runner(~S,~C,~R,~E,~P,~Rest,~take,~put,~call,~declaration),~scan,setup,D.requirement(~S,~R,~P,~Rest,~take,~put,~call,declaration),D.define(~S,~C,~R,~E,~P,~Rest,~take,~put,~call,~declaration,world,name))
88def status_text(~S:Data,value:D.Status<S>) -> String:
89 match value:
90 case D.Status{id,key,provided}:"service(" ++ U32.show(id) ++ "," ++ key ++ "," ++ Bool.show(provided) ++ ")"
91def requirement_text(~S:Data,value:SP.Requirement<S>) -> String:
92 match value:
93 case SP.Service{id}:"service:" ++ U32.show(id)
94 case SP.Component{id}:"component:" ++ U32.show(id)
95 case SP.Resource{id}:"resource:" ++ U32.show(id)
96def entry_text(~S:Data,value:Fragment.Entry<S>) -> String:
97 match value:
98 case Fragment.Entry{Fragment.Service{},key,name}:"Service(" ++ key ++ "," ++ name ++ ")"
99 case _:"nonservice"
100def step_text(value:Sch.Step) -> String:
101 match value:
102 case Sch.Barrier{}:"barrier"
103 case Sch.Phase{name}:"phase:" ++ name
104 case Sch.System{id,condition}:"system:" ++ U32.show(id) ++ ":" ++ U32.show(condition)
105
106
107def text(~S:Data,value:Maybe<&2,Inventory<S>>) -> String:
108 match value:
109 case None{}:"debug=None"
110 case Some{Inventory{entries,statuses,required,ns,id,name,access,cursor,steps}}:"debug{entries=" ++ List.show(&2,Fragment.Entry<S>,entry_text(~S),entries) ++ ";services=" ++ List.show(&2,D.Status<S>,status_text(~S),statuses) ++ ";required=" ++ List.show(&2,SP.Requirement<S>,requirement_text(~S),required) ++ ";registry=" ++ U32.show(ns) ++ ":" ++ U32.show(id) ++ ":" ++ name ++ ":" ++ List.show(&2,String,s => s,access) ++ ":" ++ Tick.cursor_show(cursor) ++ ";steps=" ++ List.show(&2,Sch.Step,step_text,steps) ++ "}"
111
112
113def read(~S:Data,~C:Type,~R:Type,~E:Data,~runner:W.World<S,C,R,E> -> Unit -> Sys.Outcome<W.World<S,C,R,E>,Unit,Unit>,~scan:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,D.Status<S>>) -> Cap.ValueRead<Application<S,C,R,E,runner,scan>,Maybe<&2,Inventory<S>>>:
114 Cap.ValueRead{snapshot(~S,~C,~R,~E,~runner,~scan)}