decode_local.bend

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

1import bendvy-ecs-core@0.1.0.1/persistence_declaration.bend as Decl
2import bendvy-ecs-core@0.1.0.1/bundle_delivery.bend as Delivery
3import Base
4import entity_key.bend as Key
5import bendvy-ecs-core@0.1.0.1/decode_frame.bend as F
6import bendvy-ecs-core@0.1.0.1/decode_requests.bend as Request
7import bendvy-ecs-core@0.1.0.1/decode_owned_journal.bend as Journal
8import bendvy-ecs-core@0.1.0.1/ordinary_declaration.bend as Identity
9import bendvy-ecs-core@0.1.0.1/decode_data.bend as D
10import bendvy-ecs-core@0.1.0.1/world.bend as W
11import bendvy-ecs-core@0.1.0.1/local.bend as Local
12import bendvy-ecs-core@0.1.0.1/transaction.bend as T
13import bendvy-ecs-core@0.1.0.1/commands.bend as Commands
14import bendvy-ecs-core@0.1.0.1/bundle_batch.bend as Batch
15
16# State/sink adapters are application-selected, closed typed functions. A failed
17# run returns its Local owner and no output, exactly like existing Local.Outcome.
18def registered(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~A:Type,~Error:Data,~Out:Type,~runner:W.World<S,C,R,E> -> L -> A -> Local.Outcome<W.World<S,C,R,E>,L,Error,Out>,world:W.World<S,C,R,E>,name:String,access:List<&2,String>,local:L) -> Local.Registered<S,C,R,E,L,A,Error,Out,runner>:
19  Local.register(~S,~C,~R,~E,~L,~A,~Error,~Out,~runner,world,name,access,local)
20
21def succeeded(~World:Type,~L:Type,~Error:Data,~Out:Type,world:World,result:L & Out) -> Local.Outcome<World,L,Error,Out>:
22  match result:
23    case (local,output):Local.Succeeded{world,local,output}
24
25def committed(~World:Type,~L:Type,~A:Type,~Rows:Data,~Error:Data,~Out:Type,~success:L -> A -> Rows -> L & Out,~failure:L -> A -> L,local:L,args:A,rows:Rows,result:T.Returned<World,Error>) -> Local.Outcome<World,L,Error,Out>:
26  match result:
27    case T.Returned{world,T.Success{}}:succeeded(~World,~L,~Error,~Out,world,success(local,args,rows))
28    case T.Returned{world,T.Failure{error}}:Local.Failed{world,failure(local,args),error}
29
30def recovered(~S:Data,~World:Type,~L:Type,~A:Type,~P:Type,~Q:Type,~Error:Data,~Out:Type,~recover:L -> A -> List<Request.Packet<P>> -> List<Journal.Pending<Q>> -> L,error:Error,local:L,args:A,prepared:List<Batch.Prepared<S,Request.Packet<P>>>,pending:List<Journal.Pending<Q>>,result:Journal.Returned<World,Request.Packet<P>,Q>) -> Local.Outcome<World,L,Error,Out>:
31  match result:
32    case Journal.Returned{world,owners,more}:Local.Failed{world,recover(local,args,List.append(&1,Request.Packet<P>,owners,Batch.originals(~S,~Request.Packet<P>,prepared)),List.append(&1,Journal.Pending<Q>,pending,more)),error}
33
34def abort(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Q:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~L:Type,~A:Type,~Error:Data,~Out:Type,~recover:L -> A -> List<Request.Packet<P>> -> List<Journal.Pending<Q>> -> L,error:Error,local:L,args:A,frame:F.Frame<S,C,R,E,P,Q,identity,project>) -> Local.Outcome<W.World<S,C,R,E>,L,Error,Out>:
35  match frame:
36    case F.Frame{Request.Owner{Batch.Batch{tx,prepared},_},_,_,_,receipts,pending}:recovered(~S,~W.World<S,C,R,E>,~L,~A,~P,~Q,~Error,~Out,~recover,error,local,args,prepared,pending,Journal.abort(~W.World<S,C,R,E>,~E,~Request.Packet<P>,~Q,receipts,tx))
37
38# Non-empty deferred packets require the separate deferred completion route.
39# Pending is never silently accepted as a completed rollback.
40def traversal(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Q:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~L:Type,~A:Type,~Rows:Data,~Error:Data,~Out:Type,~success:L -> A -> Rows -> L & Out,~failure:L -> A -> L,~recover:L -> A -> List<Request.Packet<P>> -> List<Journal.Pending<Q>> -> L,rejected:Error,local:L,result:F.Frame<S,C,R,E,P,Q,identity,project> & (A & (T.Outcome<Error> & Rows))) -> Local.Outcome<W.World<S,C,R,E>,L,Error,Out>:
41  match result:
42    case (F.Frame{Request.Owner{Batch.Batch{tx,[]},_},_,_,_,_,[]},(args,(T.Success{},rows))):committed(~W.World<S,C,R,E>,~L,~A,~Rows,~Error,~Out,~success,~failure,local,args,rows,Commands.tx_finish(~S,~C,~R,~E,~Error,tx,T.Success{}))
43    case (frame,(args,(T.Success{},_))):abort(~S,~C,~R,~E,~P,~Q,~identity,~project,~L,~A,~Error,~Out,~recover,rejected,local,args,frame)
44    case (frame,(args,(T.Failure{error},_))):abort(~S,~C,~R,~E,~P,~Q,~identity,~project,~L,~A,~Error,~Out,~recover,error,local,args,frame)
45
46def deferred(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Error:Data,~L:Type,~Out:Type,~recover:L -> Out -> List<Request.Packet<P>> -> L,local:L,output:Out,result:Batch.Finished<S,C,R,E,Request.Packet<P>,Error>) -> Local.Outcome<W.World<S,C,R,E>,L,Error,Out>:
47  match result:
48    case Batch.Committed{world}:Local.Succeeded{world,local,output}
49    case Batch.Failed{world,packets,error}:Local.Failed{world,recover(local,output,packets),error}
50
51# Construction uses the same retained nominal descriptor as the grants.
52def begin_owner(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,world:W.World<S,C,R,E>,codec:Decl.Constructed<S,P,identity,project>) -> Request.Owner<S,C,R,E,P,identity,project>:
53  Request.Owner{Batch.begin(~S,~C,~R,~E,~Request.Packet<P>,T.begin(~W.World<S,C,R,E>,~E,world)),codec}
54def begin_frame(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Q:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,world:W.World<S,C,R,E>,codec:Decl.Constructed<S,P,identity,project>) -> F.Frame<S,C,R,E,P,Q,identity,project>:
55  F.Frame{begin_owner(~S,~C,~R,~E,~P,~identity,~project,world,codec),W.Handle{0,Key.EntityKey{0,0}},None{},None{},[],[]}
56def finish_deferred(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Error:Data,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~attempt:W.World<S,C,R,E> -> W.Handle<S> -> Request.Packet<P> -> Delivery.Delivery<W.World<S,C,R,E>,Request.Packet<P>>,~delivery_recover:W.World<S,C,R,E> -> Request.Packet<P> -> W.WorldError -> W.World<S,C,R,E>,~L:Type,~Out:Type,~recover:L -> Out -> List<Request.Packet<P>> -> L,local:L,output:Out,owner:Request.Owner<S,C,R,E,P,identity,project>,outcome:T.Outcome<Error>) -> Local.Outcome<W.World<S,C,R,E>,L,Error,Out>:
57  deferred(~S,~C,~R,~E,~P,~Error,~L,~Out,~recover,local,output,Request.finish(~S,~C,~R,~E,~P,~Error,~identity,~project,~attempt,~delivery_recover,owner,outcome))