skip to content
==> include/mesh/placer.h <==
1/* @ajax/mesh-placer: one placed program's state machine (place.rs Placer), sans-IO. The driver feeds
2 * it events (a frame batch completed here, a peer frame arrived, a control request, the fleet's view,
3 * a tick) and carries out the acts it returns (send a frame, write the state into the view, show a
4 * composed frame, publish the follow batch, change the run state, answer a request).
5 *
6 * The fleet's leader coordinates every change among the up members: it pauses the others (PL_PAUSE),
7 * collects their drained state and time per part (PL_PAUSED), picks the state that continues, sets the
8 * new mode everywhere (PL_SET with that state) and waits for PL_DONE; a change not done in 5 s is
9 * rolled back (PL_FAIL). It re-plans when a member of the mode drops, and 5 s after one comes back.
10 * Frames go point to point. Nothing here knows doom: the manifest's regions say what moves. Times are
11 * monotonic microseconds. */
12#ifndef MESH_PLACER_H
13#define MESH_PLACER_H
14
15#include "mesh/place_compose.h"
16#include "mesh/place_mode.h"
17#include "mesh/place_spec.h"
18#include "mesh/place_wire.h"
19#include "mesh/mt.h"
20
21#include <stdbool.h>
22#include <stdint.h>
23
24#define MPL_CHANGE_TIMEOUT_US 5000000ull /* a change that has not finished by then is rolled back */
25#define MPL_JOIN_DWELL_US 5000000ull     /* after a member comes back, the leader waits this long */
26
27/* Where a frame goes: one member, or every member in a mask. */
28typedef struct {
29    bool to_mask;
30    uint32_t k; /* to, or the mask */
31} mpl_dest;
32
33typedef enum {
34    MPL_SEND,        /* dest, bytes: a whole peer frame (type byte first) */
35    MPL_WRITE_STATE, /* bytes: the state regions into the view (only while nothing is in flight) */
36    MPL_SHOW,        /* frame, sys (SHB_SYS), bytes (the buffer), lat_us: a whole frame into the show region */
37    MPL_FOLLOW,      /* frame: publish the follow batch (OP_FOLLOW, this system's parts) */
38    MPL_MODE,        /* mode: the mode changed here (run state, PX_PLACE, SH_MODE) */
39    MPL_ANSWER,      /* handle, ok, text: answer a local request */
40    MPL_LOG,         /* text */
41} mpl_act_kind;
42
43typedef struct {
44    mpl_act_kind kind;
45    mpl_dest dest;
46    mpw_bytes bytes;
47    uint32_t frame, sys, lat_us;
48    mpm_mode mode;
49    uint64_t handle;
50    bool ok;
51    char *text;
52} mpl_act;
53
54typedef struct {
55    mpl_act *v;
56    size_t n, cap;
57} mpl_acts;
58
59void mpl_acts_free(mpl_acts *a);
60
61typedef struct {
62    uint64_t shown, lat_n, lat_sum_us;
63    uint32_t lat_max_us;
64    uint64_t ignored; /* peer frames this role had no use for */
65} mpl_stats;
66
67typedef struct mpl_placer mpl_placer;
68
69/* Takes spec. log: an optional line logger (the Rust's info! lines that are not acts). */
70mpl_placer *mpl_new(const char *name, mps_spec spec, uint32_t me, uint32_t n);
71void mpl_free(mpl_placer *p);
72void mpl_set_log(mpl_placer *p, void (*log)(void *ctx, const char *line), void *ctx);
73
74const mpm_mode *mpl_mode(const mpl_placer *p);
75mpm_role mpl_role(const mpl_placer *p);
76bool mpl_paused(const mpl_placer *p);
77bool mpl_busy(const mpl_placer *p);
78uint32_t mpl_members(const mpl_placer *p);
79uint32_t mpl_my_parts(const mpl_placer *p);
80const mpl_stats *mpl_stats_of(const mpl_placer *p);
81void mpl_set_part_ns(mpl_placer *p, uint32_t ns); /* this machine's mean time per part, for split auto */
82const mps_spec *mpl_spec(const mpl_placer *p);
83
84/* A control request's words, as the cluster's size allows them. */
85bool mpl_parse(const mpl_placer *p, char *const *words, size_t n, mpm_target *out, char **err);
86/* The target of a request over the members that are up now. */
87bool mpl_plan(const mpl_placer *p, const mt_strs *words, mpm_target *out, char **err);
88
89/* The leader's request (the committed placement request): plan it over the up members, run the change. */
90mpl_acts mpl_request(mpl_placer *p, const mt_strs *words, uint64_t handle, uint64_t now);
91/* The fleet's view changed: the up members, the leader (has_coord), the committed request (NULL: local). */
92mpl_acts mpl_view(mpl_placer *p, uint32_t up, bool has_coord, uint32_t coord, const mt_strs *request, uint64_t now);
93/* Per driver tick: drained (nothing of the program in flight here) and this machine's state regions,
94 * read on demand. */
95typedef mpw_bytes (*mpl_state_fn)(void *ctx);
96mpl_acts mpl_tick(mpl_placer *p, uint64_t now, bool drained, mpl_state_fn state, void *ctx);
97/* A peer F_PLACE from system from (takes m). */
98mpl_acts mpl_peer_place(mpl_placer *p, mpw_place m, uint32_t from, uint64_t now);
99/* A whole batch of this machine's own frame finished (Runner: every part; Owner: its parts). Takes the bytes. */
100mpl_acts mpl_own_frame(mpl_placer *p, uint32_t frame, mpw_bytes state, mpw_bytes data, uint64_t now);
101/* The follow batch (Follower) finished: its parts' data (taken). */
102mpl_acts mpl_follow_done(mpl_placer *p, mpw_bytes data, uint64_t now);
103/* The follow batch was lost (the kernel halted under it). */
104void mpl_follow_lost(mpl_placer *p);
105/* A peer F_FRAME (takes m). */
106mpl_acts mpl_peer_frame(mpl_placer *p, mpw_frame m, uint64_t now);
107/* Unloaded / its manifest's placement changed: answer what waits. */
108mpl_acts mpl_drop_all(mpl_placer *p, const char *why);
109
110#endif