==> include/mesh/fleet_doc.h <==1/* @ajax/mesh-fleet-doc: the fleet's desired state (fleet.rs Doc): the programs that should be loaded
2 * (catalog dir, image hash, run state, a reset generation, the previous image for a rollback, the
3 * scheduling needs, the scheduler's placement, a migration in flight, the operator's pin), the
4 * lockstep groups (program, ordered members, epoch, cycle, state, on-loss policy), the placement
5 * requests and the scheduler's switches. Text, one line per item; a few hundred bytes. The leader
6 * sends it whole. */
7#ifndef MESH_FLEET_DOC_H
8#define MESH_FLEET_DOC_H
9
10#include "mesh/abi/base.h"
11#include "mesh/member_list.h"
12#include "mesh/sched_needs.h"
13#include "mesh/mt.h"
14
15#include <stdbool.h>
16#include <stdint.h>
17
18/* A program the fleet should run (every member that can, or where the scheduler placed it). */
19typedef struct {
20 char *dir; /* the catalog dir its image comes from */
21 uint64_t hash; /* the image hash */
22 bool run;
23 uint32_t reset; /* bumped by `reset <name>` */
24 bool lockstep; /* peer = "lockstep": it runs as a lockstep group */
25 mt_strs backends; /* the manifest's backends */
26 bool has_prev; /* the image before the last upgrade, for `rollback` */
27 char *prev_dir;
28 uint64_t prev_hash;
29 mesh_needs needs; /* the manifest's scheduling keys */
30 ml_opt at; /* the scheduler's placement (none: every member that can) */
31 bool has_from; /* a migration in flight: the member whose view the new member takes */
32 uint32_t from;
33 bool has_to; /* the migration's target, and the version that started it */
34 uint32_t to;
35 uint64_t since;
36 ml_opt pin; /* `sched pin`: the operator's placement */
37 char *why; /* why it is where it is */
38} mfd_prog;
39
40/* A ProgSpec with Rust's empty/None defaults and these needs (copied). */
41mfd_prog mfd_prog_new(const char *dir, uint64_t hash, bool run, const mesh_needs *needs);
42mfd_prog mfd_prog_clone(const mfd_prog *p);
43bool mfd_prog_eq(const mfd_prog *a, const mfd_prog *b);
44void mfd_prog_free(mfd_prog *p);
45/* Whether member k should have it loaded (placed there, or the source of its migration). */
46bool mfd_prog_here(const mfd_prog *p, uint32_t k);
47
48/* What a lockstep group's latest cycle did. */
49typedef enum { MFD_OP_NONE, MFD_OP_UPGRADE, MFD_OP_ROLLBACK, MFD_OP_TASK } mfd_op_kind;
50typedef struct {
51 mfd_op_kind kind;
52 uint32_t op, arg; /* a task's */
53} mfd_op;
54
55typedef enum { MFD_RUNNING, MFD_PAUSED } mfd_gstate;
56typedef enum { MFD_LOSS_PAUSE, MFD_LOSS_REFORM } mfd_onloss;
57
58typedef struct {
59 char *name, *program;
60 uint32_t epoch, cycle;
61 mfd_op op;
62 ml_list members; /* rank r is members[r] */
63 mfd_gstate state;
64 mfd_onloss on_loss;
65 uint32_t auto_ms; /* with on_loss reform: re-form after this long paused (0: only when asked) */
66} mfd_group;
67
68uint32_t mfd_group_mask(const mfd_group *g);
69bool mfd_group_rank(const mfd_group *g, uint32_t k, uint32_t *rank);
70/* The rank order as bytes (F_HELLO): members[r], 0xff past the end. */
71void mfd_group_order(const mfd_group *g, uint8_t out[MESH_MAX_SYSTEMS]);
72mfd_group mfd_group_clone(const mfd_group *g);
73bool mfd_group_eq(const mfd_group *a, const mfd_group *b);
74void mfd_group_free(mfd_group *g);
75char *mfd_op_word(mfd_op op);
76bool mfd_op_parse(const char *s, mfd_op *out, char **err);
77
78typedef struct {
79 uint64_t version, term; /* term: the leader that proposed it */
80 /* programs, sorted by name */
81 char **pname;
82 mfd_prog *prog;
83 size_t nprogs;
84 mfd_group *groups;
85 size_t ngroups;
86 /* placement requests (`place <name> <words>`), sorted by program */
87 char **place_name;
88 mt_strs *place_words;
89 size_t nplaces;
90 bool sched_paused; /* `sched pause` */
91 bool autoreform; /* `sched autoreform on` */
92 uint32_t cordon; /* `sched cordon <k>`: no new placements on these members */
93} mfd_doc;
94
95mfd_doc mfd_doc_clone(const mfd_doc *d);
96bool mfd_doc_eq(const mfd_doc *a, const mfd_doc *b);
97void mfd_doc_free(mfd_doc *d);
98/* (term, version): the order of documents. */
99int mfd_id_cmp(uint64_t at, uint64_t av, uint64_t bt, uint64_t bv);
100
101mfd_prog *mfd_prog_get(const mfd_doc *d, const char *name);
102long mfd_prog_index(const mfd_doc *d, const char *name);
103/* Inserts or replaces (takes p). */
104void mfd_prog_put(mfd_doc *d, const char *name, mfd_prog p);
105bool mfd_prog_remove(mfd_doc *d, const char *name);
106mfd_group *mfd_group_of(const mfd_doc *d, const char *program);
107mfd_group *mfd_group_named(const mfd_doc *d, const char *name);
108void mfd_group_push(mfd_doc *d, mfd_group g); /* takes g */
109void mfd_group_remove_at(mfd_doc *d, size_t i);
110const mt_strs *mfd_place_get(const mfd_doc *d, const char *name);
111void mfd_place_put(mfd_doc *d, const char *name, mt_strs words); /* takes words */
112bool mfd_place_remove(mfd_doc *d, const char *name);
113
114char *mfd_encode(const mfd_doc *d);
115bool mfd_decode(const char *text, mfd_doc *out, char **err);
116
117/* Whether a member whose GPU backend is kind (BACKEND_*) can run a program listing backends (every
118 * meshd has the wasm executor; a native program is assumed). */
119bool mfd_can_run(const mt_strs *backends, uint32_t kind);
120
121#endif