daemon/dec.bend
cswap-bend-cli@0.1.0.0 · 101 lines · 19 definitions
1import Base
2import cswap-bend-cli@0.1.0.0/json.bend as Json
3import cswap-bend-cli@0.1.0.0/swlive.bend as L
4import cswap-bend-cli@0.1.0.0/store/base.bend as SBase
5import cswap-bend-cli@0.1.0.0/store/seq.bend as SSeq
6import cswap-bend-cli@0.1.0.0/clock.bend as Clock
7import cswap-bend-cli@0.1.0.0/daemon/events.bend as Ev
8import cswap-bend-cli@0.1.0.0/daemon/cadence.bend as Cad
9import cswap-bend-cli@0.1.0.0/daemon/config.bend as Cfg
10
11
12
13
14
15type Dec is Data:
16 DNone{reason: String, detail: String}
17 DExhausted{earliest: Maybe<&2, U32>}
18 DGo{to: String, to_email: String, trigger: String, left_headroom: Maybe<&2, U32>, left_recovery: Maybe<&2, U32>}
19
20
21type TickRes is Data:
22 TickRes{info: Cad.Info, events: List<&2, Json.Json>}
23
24
25type Ctx is Data:
26 Ctx{ctx: SBase.Ctx, dry_run: Bool, cfg: Cfg.Cfg, now: U32, ts: String, opts: L.Opts, active: Json.Json, next_poll: Maybe<&2, U32>}
27
28def sel_o(+c: Bool, x: Cad.Outcome, y: Cad.Outcome) -> Cad.Outcome:
29 match c:
30 case True{}:
31 x
32 case False{}:
33 y
34
35def blocked_reason(+r: String) -> Bool:
36 String.eq(r, "no-candidates") || String.eq(r, "no-comparison") || String.eq(r, "no-qualifying-candidate") || String.eq(r, "no-viable-target") || String.eq(r, "all-exhausted")
37
38def info(o: Cad.Outcome, +until: Maybe<&2, U32>, +long: Bool, +idle: Bool, +np: Maybe<&2, U32>) -> Cad.Info:
39 Cad.Info{o, until, long, idle, np}
40
41def one(i: Cad.Info, +e: Json.Json) -> TickRes:
42 TickRes{i, [e]}
43
44def iso_opt(+m: Maybe<&2, U32>) -> Maybe<&2, String>:
45 match m:
46 case None{}:
47 None{}
48 case Some{t}:
49 Some{Clock.iso8601_utc(t)}
50
51def ctx_ts(+c: Ctx) -> String:
52 match c:
53 case Ctx{x, d, cf, n, ts, o, a, np}:
54 ts
55
56def ctx_np(+c: Ctx) -> Maybe<&2, U32>:
57 match c:
58 case Ctx{x, d, cf, n, ts, o, a, np}:
59 np
60
61def none_res(+c: Ctx, +reason: String, +detail: String) -> TickRes:
62 one(info(sel_o(blocked_reason(reason), Cad.Blocked{}, Cad.NoAction{}), None{}, String.eq(reason, "no-candidates"), String.eq(reason, "active-idle"), ctx_np(c)), Ev.no_switch(ctx_ts(c), reason, detail))
63
64def exhausted_res(+c: Ctx, +earliest: Maybe<&2, U32>) -> TickRes:
65 one(info(Cad.Blocked{}, earliest, False{}, False{}, ctx_np(c)), Ev.all_exhausted(ctx_ts(c), iso_opt(earliest)))
66
67
68def error_res(+c: Ctx, +msg: String) -> TickRes:
69 one(info(Cad.Failed{}, None{}, False{}, False{}, ctx_np(c)), Ev.error(ctx_ts(c), msg, True{}))
70
71
72
73def ctx_now(+c: Ctx) -> U32:
74 match c:
75 case Ctx{x, d, cf, n, ts, o, a, np}:
76 n
77
78def ctx_cfg(+c: Ctx) -> Cfg.Cfg:
79 match c:
80 case Ctx{x, d, cf, n, ts, o, a, np}:
81 cf
82
83def ctx_store(+c: Ctx) -> SBase.Ctx:
84 match c:
85 case Ctx{x, d, cf, n, ts, o, a, np}:
86 x
87
88def ctx_opts(+c: Ctx) -> L.Opts:
89 match c:
90 case Ctx{x, d, cf, n, ts, o, a, np}:
91 o
92
93def ctx_active(+c: Ctx) -> Json.Json:
94 match c:
95 case Ctx{x, d, cf, n, ts, o, a, np}:
96 a
97
98def ctx_dry(+c: Ctx) -> Bool:
99 match c:
100 case Ctx{x, d, cf, n, ts, o, a, np}:
101 d