1 import Base 2 import ./json.bend as J 3 import ./core.bend as C 4 import ./watcher.bend as W 5 6 # Store 7 # ===== 8 # 9 # kube-runtime's reflector Store, keyed as client-go's cache is ("ns/name" 10 # or "name"). A relist builds a fresh buffer between Init and InitDone and 11 # swaps it in whole, so an object deleted while the watch was down leaves 12 # the store with the relist (kube-runtime's buffered reflector). 13 14 type Store is Data: 15 Store{objs: Map<&2, J.Json>, buf: Map<&2, J.Json>, ready: Bool} 16 17 def Store.new() -> Store: 18 Store{Map.new(&2, J.Json), Map.new(&2, J.Json), False{}} 19 20 def Store.apply(s: Store, o: W.Out) -> Store: 21 match s o: 22 case Store{objs, buf, r} W.OInit{}: 23 Store{objs, Map.new(&2, J.Json), r} 24 case Store{objs, buf, r} W.OInitApply{+x}: 25 Store{objs, Map.set(&2, J.Json, buf, C.Obj.key(x), x), r} 26 case Store{objs, buf, r} W.OInitDone{}: 27 Store{buf, Map.new(&2, J.Json), True{}} 28 case Store{objs, buf, r} W.OApply{+x}: 29 Store{Map.set(&2, J.Json, objs, C.Obj.key(x), x), buf, r} 30 case Store{objs, buf, r} W.ODelete{+x}: 31 Store{Map.del(&2, J.Json, objs, C.Obj.key(x)), buf, r} 32 33 def Store.apply_all(os: List<&2, W.Out>, s: Store) -> Store: 34 match os: 35 case Nil{}: 36 s 37 case Con{o, t}: 38 Store.apply_all(t, Store.apply(s, o)) 39 40 def Store.get.fin(r: Map<&2, J.Json> & J.Json) -> Maybe<&2, J.Json>: 41 match r: 42 case (m, J.JNull{}): 43 None{} 44 case (m, x): 45 Some{x} 46 47 # The object under a key, if the store has it. 48 def Store.get(s: Store, key: String) -> Maybe<&2, J.Json>: 49 match s: 50 case Store{objs, buf, r}: 51 Store.get.fin(Map.get(J.Json, J.JNull{}, objs, key)) 52 53 def Store.ready(s: Store) -> Bool: 54 match s: 55 case Store{o, b, r}: 56 r 57 58 def Store.size(s: Store) -> Nat: 59 match s: 60 case Store{o, b, r}: 61 Map.size(&2, J.Json, o) 62 63 def Store.keys(s: Store) -> List<&2, String>: 64 match s: 65 case Store{o, b, r}: 66 Map.keys(&2, J.Json, o) 67 68 def Store.values.put(r: Map<&2, J.Json> & J.Json, rest: List<&2, J.Json>) -> List<&2, J.Json>: 69 match r: 70 case (m, x): 71 x <> rest 72 73 def Store.values.go(ks: List<&2, String>, +m: Map<&2, J.Json>) -> List<&2, J.Json>: 74 match ks: 75 case Nil{}: 76 Nil{} 77 case Con{k, t}: 78 Store.values.put(Map.get(J.Json, J.JNull{}, m, k), Store.values.go(t, m)) 79 80 def Store.values(s: Store) -> List<&2, J.Json>: 81 match s: 82 case Store{+o, b, r}: 83 Store.values.go(Map.keys(&2, J.Json, o), o)