==> src/relay.h <==1/* The fleet thread's state, shared by its source files (relay.c: events, links, changes, the leader;
2 * group.c: the lockstep data plane; sched.c: the scheduler glue and migrations; publish.c: the status
3 * block and the texts; board.c: the perf board). Not installed. */
4#ifndef RELAY_H
5#define RELAY_H
6
7#include "mesh/fleet_core.h"
8#include "mesh/fleet_store.h"
9#include "mesh/peer_link.h"
10#include "mesh/peer_relay.h"
11#include "mesh/peer_view.h"
12#include "mesh/sched_place.h"
13#include "mesh/sched_tracker.h"
14#include "mesh/mt.h"
15
16#include <pthread.h>
17#include <stdatomic.h>
18
19#define MAXS MESH_MAX_SYSTEMS
20
21uint64_t mpr_mono_ms(void);
22uint64_t mpr_mono_us(void);
23
24/* One link and what the data plane keeps per link. */
25typedef struct {
26 struct mpr_relay *r;
27 mpn_link *l;
28 uint32_t from;
29 uint64_t lid;
30 atomic_uint_fast64_t last_rx; /* this meshd's uptime ms when its last frame arrived */
31 pthread_mutex_t sent_mu; /* our rounds in flight to it: (counter, sent µs) */
32 uint64_t sent_c[64], sent_t[64];
33 size_t sent_n;
34 atomic_uint_fast64_t last_round; /* its last round counter seen here */
35 atomic_int refs; /* the rounds sender writing to it (freeing waits for 0) */
36} linkrec;
37
38typedef enum { EV_LINK, EV_CLOSED, EV_FRAME, EV_CHANGE, EV_WAKE, EV_FETCH_IMAGE, EV_FETCH_VIEW, EV_CTL_REPLY } ev_kind;
39
40/* A blocked caller's answer slot (fetches). */
41typedef struct {
42 pthread_mutex_t mu;
43 pthread_cond_t cv;
44 bool done, ok;
45 char *err;
46 mpr_payload payload;
47 uint32_t view_abi;
48 mpw_bytes view;
49} waiter;
50
51typedef struct {
52 ev_kind kind;
53 uint32_t from, id;
54 uint64_t lid, hash;
55 int fd;
56 mpk_join join;
57 atomic_bool *alive;
58 char *text, *name, *dir;
59 mpw_bytes frame;
60 mpr_reply reply;
61 waiter *w;
62 bool ok;
63} event;
64
65/* Who waits for a change's answer: a local caller (or nobody), or a member's F_CTL id. */
66typedef struct {
67 bool remote;
68 uint32_t k, id;
69 mpr_reply local;
70} replyto;
71
72/* The change the leader is committing or waiting on. */
73typedef struct {
74 char *what;
75 replyto reply;
76 uint64_t version;
77 bool committed;
78 uint32_t up; /* the members up when it committed ... */
79 uint64_t deadline; /* ... and when we stop waiting for them (ms) */
80 mfd_doc before, after;
81} pending_t;
82
83/* The leader's migration in flight. */
84typedef struct {
85 mst_move mv;
86 uint64_t version, t0_ms;
87} mig_t;
88
89typedef struct {
90 bool used;
91 uint32_t id;
92 waiter *w;
93 uint32_t from;
94 uint64_t deadline;
95} image_wait;
96
97typedef struct {
98 bool used;
99 uint32_t id;
100 waiter *w;
101 mpv_wait v;
102} view_wait;
103
104typedef struct {
105 bool used;
106 uint32_t id;
107 mpr_reply reply;
108 uint32_t leader;
109 uint64_t deadline;
110} fwd_t;
111
112/* A failure the scheduler avoids a while: (program, member) -> (hash, why, unsupported, when). */
113typedef struct {
114 char *name;
115 uint32_t k;
116 uint64_t hash;
117 char *why;
118 bool unsupported;
119 uint64_t at;
120} fail_mem_t;
121
122typedef struct {
123 char *name;
124 uint32_t k;
125 msm_perf perf;
126 uint64_t at;
127} perf_mem_t;
128
129/* The perf board: every member's last F_PERF (and when it came), and the link RTTs. */
130typedef struct {
131 pthread_mutex_t mu;
132 bool has[MAXS];
133 msr_report rep[MAXS];
134 uint64_t at_us[MAXS];
135 mof32 rtt_us[MAXS];
136} board_t;
137
138/* The lockstep rounds' tag: (epoch, cycle) and each system's rank (0xff: not in it). */
139typedef struct {
140 uint32_t epoch, cycle;
141 uint8_t rank_of[MAXS], me;
142} tag_t;
143
144struct mpr_relay {
145 mpr_host h;
146 uint32_t me, n;
147 mcc_tunables tun;
148 mpk_caps my_caps;
149 mfc_core *core;
150 mfs_store store;
151 bool has_store;
152 uint64_t t0_ms;
153 /* events */
154 pthread_mutex_t ev_mu;
155 pthread_cond_t ev_cv;
156 event *ev;
157 size_t ev_n, ev_cap;
158 pthread_t thread, sender;
159 atomic_bool quit, fatal;
160 /* links */
161 pthread_mutex_t links_mu;
162 linkrec *links[MAXS];
163 mpk_caps caps[MAXS];
164 bool has_caps[MAXS];
165 uint64_t next_lid;
166 mpn_acceptor *acceptor;
167 mpn_dialer *dialers[MAXS];
168 size_t ndialers;
169 /* members' beats */
170 mpk_beat_status st[MAXS];
171 uint64_t last_beat_ms;
172 /* changes */
173 char **queue_line;
174 replyto *queue_to;
175 size_t nqueue;
176 bool has_pending;
177 pending_t pending;
178 pending_t *waiting;
179 size_t nwaiting;
180 fwd_t fwd[64];
181 image_wait images[32];
182 view_wait views[32];
183 uint32_t next_id;
184 ms_map paused_since; /* group -> ms */
185 bool has_first_doc_at;
186 uint64_t first_doc_at_ms;
187 uint32_t seen_status[MAXS];
188 char *seen_reason[MAXS];
189 /* the driver's last view */
190 bool has_view;
191 uint32_t view_up;
192 bool view_has_leader;
193 uint32_t view_leader;
194 char *view_places;
195 /* the lockstep group */
196 pthread_mutex_t group_mu; /* the reconciler's wish */
197 bool want_set, want_mirror, want_member, want_changed;
198 mpk_hello want;
199 bool has_hello;
200 mpk_hello hello;
201 bool has_theirs[MAXS];
202 mpk_hello theirs[MAXS];
203 atomic_uint hello_state;
204 char *hello_why;
205 uint64_t hello_sent_ms;
206 bool has_mismatch[MAXS];
207 mpk_hello mismatch[MAXS];
208 atomic_bool mirroring;
209 pthread_mutex_t send_mu; /* held by the sender for a whole pass (a retag waits for it) */
210 pthread_mutex_t tag_mu;
211 tag_t tag;
212 atomic_uint_fast64_t last_sent;
213 pthread_mutex_t own_mu;
214 uint64_t own_c[64], own_t[64];
215 size_t own_n;
216 /* publishing */
217 uint64_t last_publish_ms, last_sched_text_ms;
218 /* the scheduler */
219 msw_weights w;
220 mst_tracker *tracker;
221 bool has_mig;
222 mig_t mig;
223 bool down[MAXS];
224 uint64_t down_since[MAXS];
225 perf_mem_t *perf_mem;
226 size_t nperf_mem;
227 uint64_t last_sched, last_rebalance;
228 uint32_t moves_done, last_gap_us;
229 mt_strs sched_log;
230 char *group_prop;
231 msp_explains explains;
232 fail_mem_t *fail_mem;
233 size_t nfail_mem;
234 bool has_load[MAXS];
235 mpv_load load_avg[MAXS];
236 board_t board;
237 /* What other threads may read without the core: set at the end of every tick. */
238 atomic_uint_fast64_t pub_version;
239 atomic_uint pub_leader, pub_role, pub_alive;
240};
241
242/* relay.c */
243uint64_t relay_now(const mpr_relay *r);
244void relay_send(mpr_relay *r, uint32_t k, const mpw_bytes *f);
245void relay_broadcast(mpr_relay *r, const mpw_bytes *f);
246void relay_log(mpr_relay *r, bool error, char *line); /* takes line */
247bool relay_propose(mpr_relay *r, mfd_doc doc, char *what, replyto to, uint64_t *version);
248uint32_t relay_linked_mask(mpr_relay *r);
249bool relay_linked(mpr_relay *r, uint32_t k);
250uint64_t relay_last_rx(mpr_relay *r, uint32_t k, bool *linked);
251void relay_beat_all(mpr_relay *r);
252void relay_my_status(mpr_relay *r, mpk_beat_status *out);
253void relay_reply(mpr_relay *r, replyto to, bool ok, const char *text);
254void waiter_done(waiter *w, bool ok, char *err);
255
256/* group.c */
257void group_want(mpr_relay *r);
258void group_hello(mpr_relay *r, uint32_t from, const mpk_hello *spec);
259void group_hello_send(mpr_relay *r);
260void group_pause(mpr_relay *r, const char *why);
261void group_set_state(mpr_relay *r, uint32_t s, const char *why);
262void group_round(mpr_relay *r, linkrec *lr, const uint8_t *body);
263void *group_sender(void *arg);
264
265/* sched.c (sched_publish: publish.c) */
266msm_member *sched_members(mpr_relay *r, uint64_t now, size_t *n);
267void sched_members_free(msm_member *ms, size_t n);
268msm_perfs sched_perf_map(mpr_relay *r, uint64_t now);
269mfd_doc sched_pass(mpr_relay *r, const mfd_doc *doc, uint64_t now, mt_strs *changes);
270mfd_doc sched_edit(mpr_relay *r, const mfd_doc *base, mfd_doc doc, uint64_t now, mt_strs *changes);
271void sched_schedule(mpr_relay *r, uint64_t now);
272void sched_serve_view(mpr_relay *r, uint32_t k, uint32_t id, const char *name, uint64_t hash);
273void sched_fetch_view(mpr_relay *r, const char *name, uint64_t hash, uint32_t from, waiter *w);
274void sched_view_chunk(mpr_relay *r, uint32_t id, const uint8_t *body, size_t n);
275void sched_view_timeouts(mpr_relay *r, bool has_lost, uint32_t lost);
276void sched_publish(mpr_relay *r, uint64_t now, uint32_t alive, uint32_t suspect, const mpr_recon *rs);
277void sched_log_decision(mpr_relay *r, const char *what);
278
279/* publish.c */
280void publish_all(mpr_relay *r, uint64_t now);
281void publish_member(mpr_relay *r, uint32_t k, uint32_t state, const mpk_caps *caps);
282char *publish_group_line(const mfd_group *g);
283
284/* board.c */
285void board_init(board_t *b);
286void board_free(board_t *b);
287/* An F_PERF from member from (its text). */
288void board_report(mpr_relay *r, uint32_t from, const char *text);
289
290#endif