1/* @ajax/mesh-reconcile: the reconciler (reconcile.rs). It makes this member's programs match the
2 * committed desired state, on every commit and when the member (re)joins; it is the only thing that
3 * changes the program set in a fleet. One pass:
4 * 1. the plan (mesh-fleet-plan): unload what should not be here, load what is missing, upgrade on a hash
5 * mismatch (a rollback when the retained image is the one wanted), then run states and resets. An
6 * image comes from the local catalog when its identity matches, else from a member. A program this
7 * member has no image for is reported unsupported, not failed; a failure is retried 30 s later or at
8 * the next document. Programs migrating here are loaded stopped, take their views from the source
9 * (producers first), and start (consumers first);
10 * 2. the lockstep group: a new epoch quiesces the program, sets the group words, resets it and asks the
11 * fleet thread to HELLO; a cycle inside the epoch quiesces it with rounds still mirrored, applies it
12 * and HELLOs only with the document's image and the cycle's task done here (review finding 2);
13 * 3. on the leader, the placement requests.
14 * Everything that touches the driver or the fleet thread goes through mrc_ops (the daemon wires it). */
15#ifndef MESH_RECONCILE_H
16#define MESH_RECONCILE_H
1718#include "mesh/fleet_doc.h"
19#include "mesh/fleet_plan.h"
20#include "mesh/peer_codec.h"
21#include "mesh/sched_tracker.h"
2223#include <stdbool.h>
24#include <stdint.h>
2526/* Whether this member may HELLO a group's new cycle: it runs the program at the document's image (inv:
27 * the driver's inventory after the cycle's actions) and the cycle's task, if any, ran here (task:
28 * NULL not run; else *task_ok and its error). Otherwise false with the reason. */
29bool mrc_cycle_ready(const mfd_group *g, uint64_t hash, const mfl_actual *inv, size_t ninv, const bool *task_ok, const char *task_err, char **why);
3031/* The stop order of programs moving together: a program that feeds another of them first. Returns a
32 * permutation of names (new list). */
33mt_strs mrc_stop_order(const mfd_doc *doc, const mt_strs *names);
3435typedef struct {
36 void *ctx;
37 uint32_t me;
38 /* The driver (each true with *text, or false with *err): */
39 mfl_actual *(*inventory)(void *ctx, size_t *n);
40 /* An image of name at hash: the local catalog's when it is that image, else a member's. *src is
41 * opaque to the reconciler, handed to load / upgrade and then to src_free. */
42 bool (*source)(void *ctx, const char *name, const char *dir, uint64_t hash, void **src, char **err);
43 void (*src_free)(void *ctx, void *src);
44 bool (*load)(void *ctx, void *src, bool run, char **text, char **err);
45 bool (*upgrade)(void *ctx, const char *name, void *src, char **text, char **err);
46 bool (*unload)(void *ctx, const char *name, char **text, char **err);
47 bool (*rollback)(void *ctx, const char *name, char **text, char **err);
48 bool (*prog_run)(void *ctx, const char *name, bool on, char **text, char **err);
49 bool (*reset)(void *ctx, const char *name, char **text, char **err);
50 bool (*task)(void *ctx, const char *name, uint32_t op, uint32_t arg, uint32_t *result, char **err);
51 bool (*place)(void *ctx, const char *name, const mt_strs *words, char **text, char **err);
52 /* A migrated program's view from member from (the fleet thread asks it), and writing it here. */
53 bool (*fetch_view)(void *ctx, const char *name, uint64_t hash, uint32_t from, uint32_t *view_abi, mpw_bytes *bytes, char **err);
54 bool (*view_put)(void *ctx, const char *name, uint32_t view_abi, const mpw_bytes *bytes, char **text, char **err);
55 /* The lockstep group shared with the fleet thread: stop feeding and wait until it saw it (mirror:
56 * keep exchanging rounds); the group words in the mailbox; ready for an epoch or cycle (HELLO). */
57 void (*quiesce)(void *ctx, bool mirror, bool member);
58 bool (*want_set)(void *ctx);
59 void (*group_words)(void *ctx, uint32_t rank, uint32_t n, uint32_t epoch);
60 void (*ready)(void *ctx, const mpk_hello *spec);
61 bool (*is_leader)(void *ctx);
62 /* Publishing: the reconcile status (RS_*; reason at most BEAT_REASON_MAX) with this member's move
63 * outcomes, and the programs not to try again (name, hash, unsupported, why <= 200 chars). */
64 void (*status)(void *ctx, uint64_t applied, uint32_t status, const char *reason, const mst_outcome *moves, size_t nmoves);
65 void (*fails)(void *ctx, char *const *names, const uint64_t *hashes, const bool *unsupported, char *const *whys, size_t n);
66 uint64_t (*applied)(void *ctx);
67 void (*log)(void *ctx, bool error, const char *line);
68 void (*sleep_ms)(void *ctx, uint32_t ms);
69} mrc_ops;
7071typedef struct mrc_rec mrc_rec;
7273mrc_rec *mrc_new(const mrc_ops *ops);
74void mrc_free(mrc_rec *r);
75/* A committed document (new: a version this reconciler did not see last): one pass. Returns true when
76 * it failed (retry in 30 s with mrc_retry). */
77bool mrc_document(mrc_rec *r, const mfd_doc *doc);
78/* The retry: failed programs get another go on the last document. */
79bool mrc_retry(mrc_rec *r);
8081/* A thread running a reconciler: post committed documents; it retries failures after 30 s. */
82typedef struct mrc_thread mrc_thread;
83mrc_thread *mrc_thread_start(const mrc_ops *ops);
84void mrc_post(mrc_thread *t, const mfd_doc *doc);
85void mrc_thread_stop(mrc_thread *t);
8687#endif