1 import Base 2 import ./machine.bend as M 3 import ./machine_stream_queue.bend as Queue 4 import ./execution_stream_channel.bend as Channel 5 import ./execution_composer_layout.bend as Layout 6 import ./change_tick.bend as Tick 7 8 # Public machine constructors retain their existing shape. Message sequence, 9 # namespace checks, reading and two-generation retention use the shared channel. 10 type Store<-V:Data> is Data: 11 Store{queue:Queue.Queue>,olderThrough:Nat,maintenance:Maybe<&2,Tick.Tick>} 12 type Reader<-S:Data,-K:Data,-V:Data,-origin:Layout.Layout,-route:Layout.Route> is Type: 13 Reader{namespace:U32,id:U32,cursor:Nat} 14 type Reading<-S:Data,-K:Data,-V:Data,-origin:Layout.Layout,-route:Layout.Route> is Type: 15 Read{reader:Reader,events:List<&2,M.Transition>,missed:Nat,tick:Tick.Tick} 16 Refused{reader:Reader} 17 def channel(~V:Data,store:Store) -> Channel.Store>: 18 match store: 19 case Store{queue,olderThrough,maintenance}:Channel.Store{queue,olderThrough,maintenance} 20 def stored(~V:Data,store:Channel.Store>) -> Store: 21 match store: 22 case Channel.Store{queue,olderThrough,maintenance}:Store{queue,olderThrough,maintenance} 23 def empty(~V:Data) -> Store:stored(~V,Channel.empty(~M.Transition)) 24 def publish(~V:Data,store:Store,sequence:Nat,event:M.Transition) -> Store: 25 stored(~V,Channel.publish(~M.Transition,channel(~V,store),sequence,event)) 26 def maintained(~V:Data,+sequence:Nat,tick:Tick.Tick,olderThrough:Nat,queue:Queue.Queue>) -> Store: 27 stored(~V,Channel.maintained(~M.Transition,sequence,tick,olderThrough,queue)) 28 def maintain(~V:Data,sequence:Nat,tick:Tick.Tick,store:Store) -> Store: 29 stored(~V,Channel.maintain(~M.Transition,sequence,tick,channel(~V,store))) 30 def missed(~V:Data,queue:Queue.Queue>,cursor:Nat) -> Nat: 31 Channel.missed(~M.Transition,queue,cursor) 32 def returned(~S:Data,~K:Data,~V:Data,~origin:Layout.Layout,~route:Layout.Route,reader:Reader,result:Channel.Store> & Channel.Reading>) -> Store & Reading: 33 match reader result: 34 case reader, (store,Channel.Refused{}):(stored(~V,store),Refused{reader}) 35 case Reader{namespace,id,_}, (store,Channel.Read{cursor,events,missed,tick}):(stored(~V,store),Read{Reader{namespace,id,cursor},events,missed,tick}) 36 def reading(~S:Data,~K:Data,~V:Data,~origin:Layout.Layout,~route:Layout.Route,+sequence:Nat,tick:Tick.Tick,reader:Reader,store:Store) -> Store & Reading: 37 match reader: 38 case Reader{namespace,id,+cursor}:returned(~S,~K,~V,~origin,~route,Reader{namespace,id,cursor},Channel.reading(~M.Transition,sequence,tick,cursor,channel(~V,store))) 39 def checked(~S:Data,~K:Data,~V:Data,~origin:Layout.Layout,~route:Layout.Route,allowed:Bool,sequence:Nat,tick:Tick.Tick,reader:Reader,store:Store) -> Store & Reading: 40 match reader: 41 case Reader{namespace,id,+cursor}:returned(~S,~K,~V,~origin,~route,Reader{namespace,id,cursor},Channel.checked(~M.Transition,allowed,sequence,tick,cursor,channel(~V,store))) 42 def read(~S:Data,~K:Data,~V:Data,~origin:Layout.Layout,~route:Layout.Route,namespace:Maybe<&2,U32>,sequence:Nat,tick:Tick.Tick,reader:Reader,store:Store) -> Store & Reading: 43 match reader: 44 case Reader{+actual,id,+cursor}:returned(~S,~K,~V,~origin,~route,Reader{actual,id,cursor},Channel.read(~M.Transition,namespace,actual,sequence,tick,cursor,channel(~V,store)))