1/* @ajax/mesh-sched-tracker: the rebalancer (sched.rs Tracker) and the leader's moves.
2 *
3 * A program moves only when its best alternative scores `improve` (25 %) better than where it is, for
4 * hold_ms in a row, at least dwell_ms after its last move, one migration at a time and at most per_min
5 * a minute. The owner policy (HTCondor) marks a member busy while other tenants load it (GPU share under
6 * owner_share or CPU PSI over owner_psi for owner_ms; cleared with hysteresis): a busy member's score
7 * drops by `owner`, so movable work leaves it. A lockstep group is never moved: the scheduler proposes
8 * a re-form. A move is in the document (source, target, the version that started it), so a new leader
9 * takes over a migration the old one started. */
10#ifndef MESH_SCHED_TRACKER_H
11#define MESH_SCHED_TRACKER_H
1213#include "mesh/fleet_doc.h"
14#include "mesh/sched_place.h"
1516#include <stdbool.h>
17#include <stdint.h>
1819/* A move the leader carries out: programs (an anchor and what is colocated with it, in stop order:
20 * producers first) from one member to another. */
21typedef struct {
22 mt_strs programs;
23 uint32_t from, to;
24 bool state; /* with the view (migrate = "state"), else a fresh start on to */
25 char *why;
26 bool forced; /* an operator's pin (no hysteresis) */
27} mst_move;
2829void mst_move_free(mst_move *m);
30mst_move mst_move_clone(const mst_move *m);
31bool mst_move_eq(const mst_move *a, const mst_move *b);
3233typedef struct mst_tracker mst_tracker;
3435mst_tracker *mst_new(void);
36void mst_free(mst_tracker *t);
37/* The last step's verdicts (for `sched`). */
38const mt_strs *mst_notes(const mst_tracker *t);
3940/* The owner policy: sets busy on the members (they are written). */
41void mst_owner(mst_tracker *t, msm_member *members, size_t n, uint64_t now, const msw_weights *w);
42/* Migrations in the last minute. */
43uint32_t mst_recent(mst_tracker *t, uint64_t now);
44/* A move was started (the budget and the dwell count from now). */
45void mst_moved(mst_tracker *t, const mst_move *m, uint64_t now);
46/* One rebalancing step: true with *out the move to make now (busy: a migration is in flight). */
47bool mst_step(mst_tracker *t, const msp_input *in, uint64_t now, bool busy, mst_move *out);
48/* A re-form the group should have (held hold_ms): true with the group, members and why to propose. */
49bool mst_group_step(mst_tracker *t, const msp_input *in, uint64_t now, char **group, ml_list *members, char **why);
5051/* The programs that move with name from `from` (it and, transitively, what is colocated with it
52 * there), producers first. */
53mt_strs mst_unit(const mfd_doc *doc, const char *name, uint32_t from);
54/* The document after a move starts (as version since). */
55mfd_doc mst_start_move(const mfd_doc *doc, const mst_move *m, uint64_t since);
56/* The migrations the document has in flight, as moves with the version that started each. */
57typedef struct {
58 mst_move *moves;
59 uint64_t *since;
60 size_t n;
61} mst_resumed;
62mst_resumed mst_resume_moves(const mfd_doc *doc);
63void mst_resumed_free(mst_resumed *r);
6465/* What a member's reconciler did with a program placed on it by a move: at document version, it ran
66 * there (ok, the migration's gap) or it did not. F_BEAT carries them. */
67typedef struct {
68 char *name;
69 uint64_t version;
70 bool ok;
71 uint32_t gap_us;
72} mst_outcome;
7374/* A move's verdict at the leader once the target reported every program of it at the move's version
75 * or later (or the target was lost, or waited_ms passed limit_ms): true with *ok, *why and *gap_ms
76 * (< 0: none); false while it is under way. Only the moved programs count. */
77bool mst_mig_verdict(const mst_move *m, uint64_t since, bool target_up, const mst_outcome *outs, size_t nouts, const char *reason, uint64_t waited_ms,
78 uint64_t limit_ms, bool *ok, char **why, double *gap_ms);
79/* The document after a move: from released (done) or the unit put back (reverted). */
80mfd_doc mst_end_move(const mfd_doc *doc, const mst_move *m, bool ok, const char *why);
8182#endif