daemon/plan.bend
cswap-bend-cli@0.1.0.0 · 146 lines · 23 definitions
1import Base
2import cswap-bend-cli@0.1.0.0/store.bend as Store
3import cswap-bend-cli@0.1.0.0/policy/types.bend as T
4import cswap-bend-cli@0.1.0.0/policy/usage.bend as PU
5import cswap-bend-cli@0.1.0.0/daemon/gather.bend as G
6import cswap-bend-cli@0.1.0.0/daemon/view.bend as V
7
8
9
10
11def sel_e(+c: Bool, +x: List<&2, G.Ent>, +y: List<&2, G.Ent>) -> List<&2, G.Ent>:
12 match c:
13 case True{}:
14 x
15 case False{}:
16 y
17
18def is_active(+e: G.Ent, +active: Maybe<&2, String>) -> Bool:
19 V.is_slot(active, V.ent_slot(e))
20
21def acct_disabled(+a: T.Account) -> Bool:
22 match a:
23 case T.Account{s, em, k, d}:
24 d
25
26
27def eligible(+e: G.Ent) -> Bool:
28 match e:
29 case G.Ent{s, em, o, c, a}:
30 Bool.not(acct_disabled(a))
31
32def due2(+m: Maybe<&2, T.Usage>, +now: Nat, +cfg: T.Config) -> Bool:
33 match m:
34 case Some{u}:
35 PU.poll_due(u, now, cfg)
36 case None{}:
37 False{}
38
39def due(+e: G.Ent, +us: List<&2, T.Usage>, +now: Nat, +cfg: T.Config) -> Bool:
40 due2(V.usage_for(us, V.slot_nat_of(V.ent_slot(e))), now, cfg)
41
42def stale2(+m: Maybe<&2, T.Usage>, +now: Nat, +ms: List<&2, String>) -> Bool:
43 match m:
44 case Some{u}:
45 Bool.not(PU.fresh(u, now, ms))
46 case None{}:
47 False{}
48
49def stale(+e: G.Ent, +us: List<&2, T.Usage>, +now: Nat, +ms: List<&2, String>) -> Bool:
50 stale2(V.usage_for(us, V.slot_nat_of(V.ent_slot(e))), now, ms)
51
52def fa2(+m: Maybe<&2, T.Usage>) -> Nat:
53 match m:
54 case Some{T.Usage{s, five, fr, seven, sr, ss, fa, bo, er, fl, np, pi, ad, hu, cu, se}}:
55 Maybe.default(&2, Nat, fa, 0n)
56 case _:
57 0n
58
59def fetched_at(+e: G.Ent, +us: List<&2, T.Usage>) -> Nat:
60 fa2(V.usage_for(us, V.slot_nat_of(V.ent_slot(e))))
61
62
63def active_due(+es: List<&2, G.Ent>, +us: List<&2, T.Usage>, +active: Maybe<&2, String>, +now: Nat, +cfg: T.Config) -> List<&2, G.Ent>:
64 match es:
65 case Nil{}:
66 []
67 case Con{e, t}:
68 sel_e(is_active(e, active) && eligible(e) && due(e, us, now, cfg), [e], active_due(t, us, active, now, cfg))
69
70
71def due_cands(+es: List<&2, G.Ent>, +us: List<&2, T.Usage>, +active: Maybe<&2, String>, +now: Nat, +cfg: T.Config) -> List<&2, G.Ent>:
72 match es:
73 case Nil{}:
74 []
75 case Con{e, t}:
76 sel_e(Bool.not(is_active(e, active)) && eligible(e) && due(e, us, now, cfg), e <> due_cands(t, us, active, now, cfg), due_cands(t, us, active, now, cfg))
77
78def sel_m(+c: Bool, +x: Maybe<&2, G.Ent>, +y: Maybe<&2, G.Ent>) -> Maybe<&2, G.Ent>:
79 match c:
80 case True{}:
81 x
82 case False{}:
83 y
84
85def older(+e: G.Ent, +best: Maybe<&2, G.Ent>, +us: List<&2, T.Usage>) -> Maybe<&2, G.Ent>:
86 match best:
87 case None{}:
88 Some{e}
89 case Some{b}:
90 sel_m(Nat.is_lt(fetched_at(e, us), fetched_at(b, us)), Some{e}, best)
91
92
93def oldest(+es: List<&2, G.Ent>, +us: List<&2, T.Usage>, +best: Maybe<&2, G.Ent>) -> Maybe<&2, G.Ent>:
94 match es:
95 case Nil{}:
96 best
97 case Con{e, t}:
98 oldest(t, us, older(e, best, us))
99
100def one_of(+m: Maybe<&2, G.Ent>) -> List<&2, G.Ent>:
101 match m:
102 case Some{e}:
103 [e]
104 case None{}:
105 []
106
107
108def first_pass(+es: List<&2, G.Ent>, +us: List<&2, T.Usage>, +active: Maybe<&2, String>, +now: Nat, +cfg: T.Config) -> List<&2, G.Ent>:
109 List.append(&2, G.Ent, active_due(es, us, active, now, cfg), one_of(oldest(due_cands(es, us, active, now, cfg), us, None{})))
110
111def same_slot(+a: G.Ent, +b: G.Ent) -> Bool:
112 String.eq(V.ent_slot(a), V.ent_slot(b))
113
114def in_list(+e: G.Ent, +xs: List<&2, G.Ent>) -> Bool:
115 match xs:
116 case Nil{}:
117 False{}
118 case Con{h, t}:
119 same_slot(e, h) || in_list(e, t)
120
121def exempt3(+u: T.Usage, +h: Maybe<&2, Nat>) -> Bool:
122 match u h:
123 case T.Usage{s, five, fr, seven, sr, ss, fa, bo, er, fl, Some{np}, pi, ad, hu, cu, se} Some{x}:
124 Nat.is_eq(x, 0n) && Nat.is_gt(pi, 600n)
125 case _ _:
126 False{}
127
128def exempt2(+m: Maybe<&2, T.Usage>, +now: Nat, +ms: List<&2, String>) -> Bool:
129 match m:
130 case Some{u}:
131 exempt3(u, PU.headroom(u, now, ms))
132 case None{}:
133 False{}
134
135
136def exempt(+e: G.Ent, +us: List<&2, T.Usage>, +now: Nat, +ms: List<&2, String>) -> Bool:
137 exempt2(V.usage_for(us, V.slot_nat_of(V.ent_slot(e))), now, ms)
138
139
140def escalated(+es: List<&2, G.Ent>, +us: List<&2, T.Usage>, +active: Maybe<&2, String>, +skip: List<&2, G.Ent>, +now: Nat, +cfg: T.Config, +ms: List<&2, String>) -> List<&2, G.Ent>:
141 match es:
142 case Nil{}:
143 []
144 case Con{e, t}:
145 sel_e(Bool.not(is_active(e, active)) && eligible(e) && Bool.not(in_list(e, skip)) && (due(e, us, now, cfg) || stale(e, us, now, ms)) && Bool.not(exempt(e, us, now, ms)),
146 e <> escalated(t, us, active, skip, now, cfg, ms), escalated(t, us, active, skip, now, cfg, ms))