Skip to main content

yo_resp/dispatch/cluster/
bus.rs

1//! The cluster bus, which is how nodes find each other and agree on who owns
2//! what.
3//!
4//! Every cluster node listens on a second port, the client port plus ten
5//! thousand, and speaks a small binary protocol on it that has nothing to do
6//! with RESP. Nodes ping each other about once a second, and every ping carries
7//! a header describing the sender, a handful of gossip entries describing other
8//! nodes the sender has heard from lately, and a few extensions on the end. Out
9//! of that falls everything a cluster knows: who exists, who owns which slots,
10//! who is a replica of whom, and who has stopped answering.
11//!
12//! The format here is the reference's, field for field and offset for offset,
13//! because the whole point of it is that a yo node and a real Redis node can be
14//! in the same cluster. The reference guarantees its own layout with static
15//! asserts in `cluster_legacy.h`, which is a promise that the offsets are part
16//! of the protocol and not an accident of one compiler, so copying them is
17//! reading a specification rather than reading an implementation.
18//!
19//! # Why this has its own threads
20//!
21//! Every client connection in this server is driven by a poller that lives in
22//! the binary crate, and this crate cannot reach it, so the bus cannot join it.
23//! That sounds like a limitation and is really a preference. Bus traffic is
24//! roughly one packet a second per node in a cluster that is behaving, which
25//! means a thread per link costs a thread that is asleep almost all of the time
26//! and buys code that reads top to bottom with no state machine in it. A
27//! cluster of a hundred nodes is a hundred sleeping threads, which is nothing,
28//! and a cluster larger than that is not a thing anybody runs. It is registered
29//! as a divergence anyway, because a reader who knows the reference will expect
30//! the bus to be in the event loop and should not have to find out by grep.
31//!
32//! # What is not here
33//!
34//! Modules, which are not a thing in this server at all, so the packet type that
35//! carries a module message between nodes is recognised and dropped.
36
37use std::io::{Read, Write};
38use std::net::{Shutdown, TcpListener, TcpStream};
39use std::sync::atomic::Ordering::Relaxed;
40use std::sync::atomic::{AtomicBool, AtomicU64};
41use std::sync::{Arc, Mutex};
42use std::time::Duration;
43
44use yo_common::lock::Lock;
45use yo_common::{Code, Error};
46
47use super::super::Server;
48use super::super::pubsub::{self, Kind};
49use super::{
50    FLAG_FAIL, FLAG_HANDSHAKE, FLAG_MASTER, FLAG_MEET, FLAG_MIGRATE_TO, FLAG_MYSELF, FLAG_NOADDR,
51    FLAG_NOFAILOVER, FLAG_PFAIL, FLAG_SLAVE, Map, Node, SLOTS, new_id,
52};
53use crate::reply::Out;
54
55// ------------------------------------------------------------- the wire format
56
57/// The four bytes every packet starts with, which is the only thing that tells
58/// a bus port from anything else somebody might connect to it.
59const SIG: &[u8; 4] = b"RCmb";
60
61/// The protocol version. A packet claiming anything else is dropped without a
62/// word, because a node that cannot read a packet cannot say so either.
63const PROTO_VER: u16 = 1;
64
65/// How long a node id is, in bytes of lowercase hex.
66const NAME_LEN: usize = 40;
67
68/// How much room an address gets, which is enough for the longest IPv6 text
69/// form and is fixed because the header is fixed.
70const IP_LEN: usize = 46;
71
72/// The slot bitmap, one bit per slot.
73const BITMAP_LEN: usize = SLOTS / 8;
74
75/// The header every packet carries, whatever its type. The reference calls this
76/// `CLUSTERMSG_MIN_LEN` and asserts it.
77const HDR_LEN: usize = 2256;
78
79/// One gossip entry.
80const GOSSIP_LEN: usize = 104;
81
82/// The most a packet may be before it is treated as noise rather than as a
83/// packet. The reference grows its receive buffer to whatever the header claims,
84/// which is fine when the peer is trusted and is a way to be talked into
85/// allocating a lot when it is not, so there is a ceiling here. A publish of a
86/// megabyte over the bus is already an unusual thing to do.
87const MAX_PACKET: usize = 64 * 1024 * 1024;
88
89/// Where each header field starts. These are the reference's, and the reference
90/// asserts them, so they are the protocol.
91const O_TOTLEN: usize = 4;
92const O_VER: usize = 8;
93const O_PORT: usize = 10;
94const O_TYPE: usize = 12;
95const O_COUNT: usize = 14;
96const O_CURRENT_EPOCH: usize = 16;
97const O_CONFIG_EPOCH: usize = 24;
98const O_OFFSET: usize = 32;
99const O_SENDER: usize = 40;
100const O_SLOTS: usize = 80;
101const O_SLAVEOF: usize = 2128;
102const O_MYIP: usize = 2168;
103const O_EXTENSIONS: usize = 2214;
104const O_PPORT: usize = 2246;
105const O_CPORT: usize = 2248;
106const O_FLAGS: usize = 2250;
107const O_STATE: usize = 2252;
108const O_MFLAGS: usize = 2253;
109
110/// Where each field of a gossip entry starts, from the start of the entry.
111const G_NAME: usize = 0;
112const G_PING: usize = 40;
113const G_PONG: usize = 44;
114const G_IP: usize = 48;
115const G_PORT: usize = 94;
116const G_CPORT: usize = 96;
117const G_FLAGS: usize = 98;
118
119/// The message types, which are the reference's numbers and cannot move.
120const T_PING: u16 = 0;
121const T_PONG: u16 = 1;
122const T_MEET: u16 = 2;
123const T_FAIL: u16 = 3;
124const T_PUBLISH: u16 = 4;
125const T_AUTH_REQUEST: u16 = 5;
126const T_AUTH_ACK: u16 = 6;
127const T_UPDATE: u16 = 7;
128const T_MFSTART: u16 = 8;
129const T_MODULE: u16 = 9;
130const T_PUBLISHSHARD: u16 = 10;
131
132/// The message flag a master sets on everything it sends while it is holding its
133/// clients still for a manual failover.
134///
135/// It is what turns the offset in the header into a promise: a header with this
136/// on says nothing has been written since that offset and nothing will be, so a
137/// replica that has caught up to it has caught up for good.
138const MF_PAUSED: u8 = 1;
139
140/// The message flag that says vote for me even though my master is up, which is
141/// the only thing that makes a manual failover different from any other on the
142/// side being asked.
143const MF_FORCEACK: u8 = 2;
144
145/// The one message flag that goes out on everything, which says this node
146/// understands the extensions on the end of a ping and is safe to send them to.
147const MF_EXT_DATA: u8 = 4;
148
149/// The extension types.
150const X_HOSTNAME: u16 = 0;
151const X_HUMAN_NAME: u16 = 1;
152const X_FORGOTTEN: u16 = 2;
153const X_SHARDID: u16 = 3;
154const X_SECRET: u16 = 4;
155
156/// `CLUSTER_OK` and `CLUSTER_FAIL`, which is the one byte of state a packet
157/// carries and is what lets a node see that the rest of the cluster has given
158/// up even when it has not.
159const STATE_OK: u8 = 0;
160const STATE_FAIL: u8 = 1;
161
162/// How long a node id stays unwelcome after `CLUSTER FORGET`, in milliseconds.
163///
164/// Forgetting a node means nothing on its own, because the next gossip packet
165/// from anybody who has not forgotten it would put it straight back. So a forget
166/// is a forget plus a minute of refusing to learn it again, by which time the
167/// forget has been passed round the cluster in the extension that carries it.
168const BLACKLIST_MS: u64 = 60_000;
169
170/// How often the bus wakes up, which is the reference's `clusterCron`.
171const CRON_MS: u64 = 100;
172
173/// How often a node is pinged when nothing else has prompted a ping. The
174/// reference derives this from the node timeout and lets it be set outright;
175/// this is the derived default.
176const PING_MS: u64 = 1000;
177
178/// How long a node has to be silent before this one calls it possibly failed.
179const NODE_TIMEOUT_MS: u64 = 15_000;
180
181/// How long to wait on a connect to another node's bus port before giving up
182/// and trying again on the next tick.
183const CONNECT_TIMEOUT: Duration = Duration::from_millis(500);
184
185/// The fixed part of the wait before a replica asks to be promoted.
186///
187/// Long enough for the FAIL message to have got round the cluster, because a
188/// vote asked for before the electorate agrees the master is gone is a vote
189/// nobody may grant. The reference adds a random part on top of the same size,
190/// which is what keeps two replicas that noticed at the same moment from asking
191/// at the same moment.
192const ELECTION_DELAY_MS: u64 = 500;
193
194/// How much later a replica asks for every other replica that holds more data
195/// than it does.
196///
197/// This is the whole of how the cluster picks the best replica without anybody
198/// comparing offsets: the one with the most data asks first, and the others are
199/// still waiting when it has already won.
200const RANK_DELAY_MS: u64 = 1000;
201
202/// How long an election may take before it is written off, and how long after
203/// that before another one is started.
204///
205/// Timeout is twice the node timeout with a floor of two seconds and retry is
206/// twice the timeout, which are the reference's numbers. The gap between them is
207/// what keeps a replica that cannot win from asking again and again and running
208/// the epoch up on every master in the cluster.
209const ELECTION_TIMEOUT_MS: u64 = if NODE_TIMEOUT_MS * 2 > 2000 {
210    NODE_TIMEOUT_MS * 2
211} else {
212    2000
213};
214
215/// How stale a replica's data may be and still be worth promoting.
216///
217/// The reference works this out from `repl-ping-replica-period` and
218/// `cluster-replica-validity-factor`, neither of which is in the config table
219/// yet, so this is those two at their defaults: ten seconds of ping period plus
220/// ten node timeouts. A replica further behind than that is one whose master was
221/// unreachable long before it died, and promoting it would lose more than
222/// letting the shard stay down does.
223const STALE_DATA_MS: u64 = 10_000 + NODE_TIMEOUT_MS * 10;
224
225/// How long a manual failover has to finish before it is written off.
226///
227/// The reference's `CLUSTER_MF_TIMEOUT`. It is short because everything it is
228/// waiting for is quick: a packet to the master, the master stopping its writes,
229/// and one round of replication to catch this node up on whatever was already in
230/// flight. If that has not happened in five seconds it is not going to.
231const MANUAL_TIMEOUT_MS: u64 = 5000;
232
233/// How much longer than that the master holds its clients still.
234///
235/// The reference's `CLUSTER_MF_PAUSE_MULT`, and the reason it is longer is that
236/// the master has to still be holding them when the replica gives up, or the
237/// window it was there to close would open again at exactly the wrong moment.
238const MANUAL_PAUSE_MULT: u64 = 2;
239
240/// What the master's offset reads as before the master has said what it is.
241///
242/// The reference uses minus one in a signed field. A real offset can be any
243/// value a `u64` holds except this one, which needs a stream longer than the age
244/// of the universe to reach.
245const OFFSET_UNKNOWN: u64 = u64::MAX;
246
247/// The election this node is standing in or voting in.
248///
249/// Atomics rather than a lock because they are read from the cron and written
250/// from whichever link thread a packet arrived on, and nothing here is read
251/// together with anything else here except by the cron, which is the only writer
252/// of everything but the count.
253#[derive(Default)]
254pub(super) struct Vote {
255    /// The epoch this node last gave its vote away in, which is the reference's
256    /// `lastVoteEpoch` and is the whole of one vote per epoch.
257    given: AtomicU64,
258    /// When this node may start asking, or nought when it never has.
259    at: AtomicU64,
260    /// How many votes have come back for the election in `epoch`.
261    count: AtomicU64,
262    /// The epoch this node is standing in.
263    epoch: AtomicU64,
264    /// How many replicas of the same master held more data than this one when
265    /// the delay was worked out, which is what that delay is made of.
266    rank: AtomicU64,
267    /// Whether the request has gone out, so that a reply is worth counting and
268    /// the delay is not recomputed underneath it.
269    sent: AtomicBool,
270}
271
272impl Vote {
273    /// The epoch this node last voted in, for the config file.
274    pub(super) fn given(&self) -> u64 {
275        self.given.load(Relaxed)
276    }
277
278    /// Put back what the config file said, which is why the file has it.
279    pub(super) fn reload(&self, epoch: u64) {
280        self.given.store(epoch, Relaxed);
281    }
282}
283
284/// The manual failover this node is in, on whichever side of it.
285///
286/// The same four words serve the replica that asked and the master that was
287/// asked, because a node is only ever on one side of one of these at a time and
288/// `held` says which side that is. Nothing here is on disk: a manual failover
289/// that was interrupted by a restart is one nobody is waiting for any more.
290pub(super) struct Manual {
291    /// When this is given up on, or nought when there is not one running.
292    end: AtomicU64,
293    /// Whether the replica may stand now, which on this path means at once and
294    /// without any of the waiting an automatic failover does.
295    can_start: AtomicBool,
296    /// The offset the master had when it stopped taking writes, or
297    /// [`OFFSET_UNKNOWN`] before it has said.
298    offset: AtomicU64,
299    /// On the master, the deadline of the pause it armed, which is both how it
300    /// lifts exactly that pause afterwards and how this node knows it is the
301    /// master here rather than the replica.
302    held: AtomicU64,
303}
304
305impl Default for Manual {
306    fn default() -> Manual {
307        Manual {
308            end: AtomicU64::new(0),
309            can_start: AtomicBool::new(false),
310            offset: AtomicU64::new(OFFSET_UNKNOWN),
311            held: AtomicU64::new(0),
312        }
313    }
314}
315
316/// Read a big endian field out of a packet, or nought when it is off the end.
317///
318/// Every read here is bounds checked rather than trusted, because the packet
319/// came off a socket and the length checks in front of it are checks and not
320/// proofs. A truncated field reading as nought loses a packet, which is what
321/// losing a packet on a gossip protocol is for.
322fn be16(p: &[u8], at: usize) -> u16 {
323    p.get(at..at + 2)
324        .map_or(0, |b| u16::from_be_bytes([b[0], b[1]]))
325}
326
327fn be32(p: &[u8], at: usize) -> u32 {
328    p.get(at..at + 4)
329        .map_or(0, |b| u32::from_be_bytes([b[0], b[1], b[2], b[3]]))
330}
331
332fn be64(p: &[u8], at: usize) -> u64 {
333    p.get(at..at + 8).map_or(0, |b| {
334        u64::from_be_bytes([b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]])
335    })
336}
337
338/// Put a big endian field into a packet being built, which is always in range
339/// because the buffer was sized first.
340fn put16(p: &mut [u8], at: usize, v: u16) {
341    p[at..at + 2].copy_from_slice(&v.to_be_bytes());
342}
343
344fn put64(p: &mut [u8], at: usize, v: u64) {
345    p[at..at + 8].copy_from_slice(&v.to_be_bytes());
346}
347
348/// A fixed width text field, which is NUL padded and may not be terminated when
349/// it is exactly full.
350fn text(p: &[u8], at: usize, len: usize) -> String {
351    let Some(raw) = p.get(at..at + len) else {
352        return String::new();
353    };
354    let end = raw.iter().position(|b| *b == 0).unwrap_or(len);
355    String::from_utf8_lossy(&raw[..end]).into_owned()
356}
357
358/// A node id out of a packet, which has to be forty hex characters or it is not
359/// one. An id that is all zeros is the reference's way of saying no node, and
360/// comes back as `None` here so the caller cannot mistake it for one.
361fn node_id(p: &[u8], at: usize) -> Option<String> {
362    let raw = p.get(at..at + NAME_LEN)?;
363    if raw.iter().all(|b| *b == 0) {
364        return None;
365    }
366    if !raw.iter().all(u8::is_ascii_hexdigit) {
367        return None;
368    }
369    Some(String::from_utf8_lossy(raw).into_owned())
370}
371
372/// Whether a slot is set in a bitmap, which the reference stores least
373/// significant bit first inside each byte.
374fn bit(bitmap: &[u8], slot: usize) -> bool {
375    bitmap
376        .get(slot / 8)
377        .is_some_and(|b| b & (1 << (slot % 8)) != 0)
378}
379
380/// Set a slot in a bitmap being built.
381fn set_bit(bitmap: &mut [u8], slot: usize) {
382    bitmap[slot / 8] |= 1 << (slot % 8);
383}
384
385/// A node index drawn at random out of `n`, which is how the gossip section
386/// picks who to talk about. Random and not round robin because every node
387/// picking independently is what spreads news in a few rounds rather than in a
388/// lap of the table.
389fn pick(n: usize) -> u16 {
390    let mut raw = [0u8; 8];
391    yo_common::entropy::fill(&mut raw);
392    (u64::from_be_bytes(raw) % n as u64) as u16
393}
394
395// ------------------------------------------------------------------ the links
396
397/// One connection to another node's bus.
398///
399/// There are two of these per pair of nodes and not one, which looks wasteful
400/// and is the reference's design for a good reason: a link is owned by whoever
401/// opened it, so a node that decides a peer is unreachable can drop its own link
402/// and reconnect without having to agree with the peer about whose turn it is.
403/// The outbound one carries this node's pings and the inbound one carries the
404/// peer's, and each is answered on the socket it arrived on.
405pub(super) struct Wire {
406    /// Whether this node accepted it rather than opened it, which is the
407    /// `from` and `to` of `CLUSTER LINKS`.
408    pub(super) inbound: bool,
409    /// The node at the far end, empty on an inbound link until a packet says
410    /// who is sending it.
411    pub(super) node: Lock<String>,
412    /// When it was made, which `CLUSTER LINKS` reports.
413    pub(super) created: u64,
414    /// The address the peer connected from or was connected to, which is how a
415    /// node learns the address of a peer that did not announce one.
416    peer: String,
417    /// The address on this side of it, which is how a node learns its own.
418    local: String,
419    /// The socket, behind a real mutex rather than the spin lock the tables use,
420    /// because writing to it blocks and a spin lock held across a blocking write
421    /// is a spin lock held for a millisecond.
422    sock: Mutex<TcpStream>,
423    /// Whether it has failed, so that a writer stops trying and the cron drops
424    /// it on the next tick.
425    dead: AtomicBool,
426    /// How many bytes have been handed to the kernel on it, which is the closest
427    /// honest answer to `CLUSTER LINKS`'s send buffer questions on a link that
428    /// has no send queue of its own.
429    sent: AtomicU64,
430}
431
432impl Wire {
433    /// Wrap an open socket.
434    fn new(sock: TcpStream, inbound: bool, node: &str, now: u64) -> Option<Arc<Wire>> {
435        let peer = sock.peer_addr().ok()?.ip().to_string();
436        let local = sock.local_addr().ok()?.ip().to_string();
437        Some(Arc::new(Wire {
438            inbound,
439            node: Lock::new(String::from(node)),
440            created: now,
441            peer,
442            local,
443            sock: Mutex::new(sock),
444            dead: AtomicBool::new(false),
445            sent: AtomicU64::new(0),
446        }))
447    }
448
449    /// The id of the node at the far end, or empty for one nobody has named.
450    fn named(&self) -> String {
451        let held = self.node.lock();
452        yo_alloc::allow(|| held.clone())
453    }
454
455    /// Point this link at a node, which happens on an inbound link the first
456    /// time a packet on it says who is sending.
457    fn name(&self, id: &str) {
458        let mut held = self.node.lock();
459        yo_alloc::allow(|| {
460            held.clear();
461            held.push_str(id);
462        });
463    }
464
465    /// Write a packet, and mark the link dead if that did not work.
466    ///
467    /// A failed write is not reported anywhere, because there is nobody to
468    /// report it to: the peer is either coming back, in which case the cron
469    /// reconnects, or it is not, in which case the timeout is the thing that
470    /// notices. That is the same as the reference, which frees the link and
471    /// carries on.
472    fn send(&self, packet: &[u8]) {
473        if self.dead.load(Relaxed) {
474            return;
475        }
476        let Ok(mut sock) = self.sock.lock() else {
477            self.dead.store(true, Relaxed);
478            return;
479        };
480        if sock.write_all(packet).is_err() {
481            self.dead.store(true, Relaxed);
482            let _ = sock.shutdown(Shutdown::Both);
483            return;
484        }
485        self.sent.store(packet.len() as u64, Relaxed);
486    }
487
488    /// Shut it down, which wakes the reader thread sitting on it.
489    fn kill(&self) {
490        self.dead.store(true, Relaxed);
491        if let Ok(sock) = self.sock.lock() {
492            let _ = sock.shutdown(Shutdown::Both);
493        }
494    }
495}
496
497/// Everything the bus owns that is not in the node table.
498///
499/// Separate from [`super::Cluster`] because none of it exists until the bus
500/// starts and none of it is looked at by a command on the hot path, so it is one
501/// lock rather than four fields on a struct every server has.
502#[derive(Default)]
503pub(super) struct Bus {
504    /// Every open link, both directions.
505    links: Lock<Vec<Arc<Wire>>>,
506    /// Ids that may not be learned again yet, and when they stop being unwelcome.
507    blacklist: Lock<Vec<(String, u64)>>,
508    /// The shared secret nodes use to recognise each other. Forty hex characters
509    /// made at start, and the whole cluster converges on whichever is smallest,
510    /// which is a rule that needs no coordinator to settle.
511    pub(super) secret: Lock<String>,
512    /// Whether the threads are up, so that starting twice is a no-op.
513    on: AtomicBool,
514    /// Whether the table has changed since it was last written.
515    dirty: AtomicBool,
516}
517
518impl Bus {
519    /// Add a link, dropping any that have died since the last look.
520    fn add(&self, wire: &Arc<Wire>) {
521        let mut links = self.links.lock();
522        yo_alloc::allow(|| {
523            links.retain(|held| !held.dead.load(Relaxed));
524            links.push(Arc::clone(wire));
525        });
526    }
527
528    /// The outbound link to a node, or `None` when there is not one.
529    fn outbound(&self, id: &str) -> Option<Arc<Wire>> {
530        let links = self.links.lock();
531        links
532            .iter()
533            .find(|held| !held.inbound && !held.dead.load(Relaxed) && *held.node.lock() == *id)
534            .map(Arc::clone)
535    }
536
537    /// Every live link, for a broadcast.
538    fn all(&self) -> Vec<Arc<Wire>> {
539        let links = self.links.lock();
540        yo_alloc::allow(|| {
541            links
542                .iter()
543                .filter(|held| !held.dead.load(Relaxed))
544                .map(Arc::clone)
545                .collect()
546        })
547    }
548
549    /// Drop every link to one node, which is what forgetting it means at this
550    /// level.
551    fn cut(&self, id: &str) {
552        let mut links = self.links.lock();
553        links.retain(|held| {
554            let theirs = held.node.lock();
555            if *theirs != *id {
556                return true;
557            }
558            drop(theirs);
559            held.kill();
560            false
561        });
562    }
563
564    /// Whether an id is unwelcome, and forget the entries that have aged out
565    /// while looking.
566    fn blacklisted(&self, id: &str, now: u64) -> bool {
567        let mut list = self.blacklist.lock();
568        list.retain(|(_, until)| *until > now);
569        list.iter().any(|(held, _)| held == id)
570    }
571
572    /// Make an id unwelcome for the next minute.
573    fn blacklist(&self, id: &str, now: u64) {
574        let mut list = self.blacklist.lock();
575        yo_alloc::allow(|| {
576            list.retain(|(held, until)| held != id && *until > now);
577            list.push((String::from(id), now + BLACKLIST_MS));
578        });
579    }
580}
581
582// ------------------------------------------------------------- starting it up
583
584impl Server {
585    /// Bring the bus up, which binds the bus port and starts the three kinds of
586    /// thread that run it.
587    ///
588    /// Called once, from whoever is about to start serving clients. A server
589    /// that is not a cluster node does nothing here and pays one relaxed load
590    /// for asking.
591    ///
592    /// # Errors
593    ///
594    /// When the bus port cannot be bound. That is fatal on a real server and is
595    /// fatal here too, because a cluster node nobody can gossip with is a node
596    /// that will be voted out of its own slots in fifteen seconds.
597    pub fn start_cluster_bus(self: &Arc<Server>) -> Result<(), String> {
598        if !self.cluster_enabled() || self.cluster.bus.on.swap(true, Relaxed) {
599            return Ok(());
600        }
601        let (port, id) = {
602            let map = self.cluster.map.lock();
603            (
604                map.nodes[0].bus,
605                yo_alloc::allow(|| map.nodes[0].id.clone()),
606            )
607        };
608        let door = TcpListener::bind(("0.0.0.0", port))
609            .map_err(|e| format!("cluster bus port {port} could not be bound: {e}"))?;
610        let _ = id;
611        let accepting = Arc::clone(self);
612        spawn("yo-bus-accept", move || accept(&accepting, &door));
613        let ticking = Arc::clone(self);
614        spawn("yo-bus-cron", move || cron(&ticking));
615        Ok(())
616    }
617}
618
619/// Start a bus thread, whose name is what a stack trace will show.
620fn spawn(name: &str, body: impl FnOnce() + Send + 'static) {
621    yo_alloc::allow(|| {
622        let _ = std::thread::Builder::new()
623            .name(String::from(name))
624            .spawn(body);
625    });
626}
627
628/// Take connections on the bus port for as long as the process lives.
629fn accept(server: &Arc<Server>, door: &TcpListener) {
630    loop {
631        let Ok((sock, _)) = door.accept() else {
632            std::thread::sleep(Duration::from_millis(CRON_MS));
633            continue;
634        };
635        let _ = sock.set_nodelay(true);
636        let now = server.now_ms();
637        let Some(wire) = Wire::new(sock, true, "", now) else {
638            continue;
639        };
640        server.cluster.bus.add(&wire);
641        let reading = Arc::clone(server);
642        spawn("yo-bus-link", move || pump(&reading, &wire));
643    }
644}
645
646/// Start the clock on a node this one could not open a link to.
647///
648/// Failure detection measures the time since a ping went out and a node with no
649/// link has had no ping to send, so without this a node whose address stops
650/// answering is retried for ever and never marked as failing. The reference
651/// does the same thing in the same place and for the same reason: it says it
652/// sent a ping now, which is true in the sense that one will go out the moment
653/// there is anything to send it down.
654fn unreachable(server: &Arc<Server>, id: &str) {
655    let mut map = server.cluster.map.lock();
656    if let Some(at) = map.find(id.as_bytes())
657        && map.nodes[usize::from(at)].ping_sent == 0
658    {
659        map.nodes[usize::from(at)].ping_sent = server.now_ms();
660    }
661}
662
663/// Open a link to a node and start reading it.
664///
665/// Returns whether it worked, which the cron uses to decide whether the node is
666/// linked. The connect is blocking with a short timeout, which is why this is
667/// never called with the node table locked.
668fn dial(server: &Arc<Server>, id: &str, host: &str, bus: u16, meet: bool) -> bool {
669    let Ok(addrs) = std::net::ToSocketAddrs::to_socket_addrs(&(host, bus)) else {
670        unreachable(server, id);
671        return false;
672    };
673    let mut sock = None;
674    for addr in addrs {
675        if let Ok(open) = TcpStream::connect_timeout(&addr, CONNECT_TIMEOUT) {
676            sock = Some(open);
677            break;
678        }
679    }
680    let Some(sock) = sock else {
681        unreachable(server, id);
682        return false;
683    };
684    let _ = sock.set_nodelay(true);
685    let now = server.now_ms();
686    let Some(wire) = Wire::new(sock, false, id, now) else {
687        unreachable(server, id);
688        return false;
689    };
690    server.cluster.bus.add(&wire);
691    // The first packet decides what this is. A node that was met by hand has to
692    // hear MEET, because that is the only packet a node will accept from
693    // somebody it has never heard of; everything else is a plain ping.
694    let packet = {
695        let mut map = server.cluster.map.lock();
696        let at = map.find(id.as_bytes());
697        if let Some(at) = at {
698            map.nodes[usize::from(at)].linked = true;
699            // The meet is sent once. If it does not land the handshake times out
700            // and the node goes away, which is what should happen to an address
701            // that has nothing at it.
702            map.nodes[usize::from(at)].flags &= !FLAG_MEET;
703            // A ping that was outstanding before the link went is left where it
704            // was, so that the clock failure detection runs on is the one that
705            // started when the node went quiet rather than one that is reset
706            // every time the link is opened again. That is the reference's
707            // `old_ping_sent` and without it a node that is up but unreachable
708            // is never given up on.
709            if !meet && map.nodes[usize::from(at)].ping_sent == 0 {
710                map.nodes[usize::from(at)].ping_sent = now;
711            }
712        }
713        ping(server, &map, if meet { T_MEET } else { T_PING }, at)
714    };
715    wire.send(&packet);
716    let reading = Arc::clone(server);
717    spawn("yo-bus-link", move || pump(&reading, &wire));
718    true
719}
720
721/// Read packets off one link until it stops giving any.
722fn pump(server: &Arc<Server>, wire: &Arc<Wire>) {
723    let sock = {
724        let Ok(held) = wire.sock.lock() else {
725            return;
726        };
727        held.try_clone()
728    };
729    let Ok(mut sock) = sock else {
730        wire.kill();
731        return;
732    };
733    let mut head = [0u8; 8];
734    let mut buf: Vec<u8> = yo_alloc::allow(|| Vec::with_capacity(HDR_LEN * 2));
735    loop {
736        if wire.dead.load(Relaxed) || sock.read_exact(&mut head).is_err() {
737            break;
738        }
739        if &head[0..4] != SIG {
740            break;
741        }
742        let total = u32::from_be_bytes([head[4], head[5], head[6], head[7]]) as usize;
743        if !(16..=MAX_PACKET).contains(&total) {
744            break;
745        }
746        yo_alloc::allow(|| {
747            buf.clear();
748            buf.resize(total, 0);
749        });
750        buf[..8].copy_from_slice(&head);
751        if sock.read_exact(&mut buf[8..]).is_err() {
752            break;
753        }
754        if !process(server, wire, &buf) {
755            break;
756        }
757    }
758    wire.kill();
759    // A link that has gone is a link this node should open again, which it will
760    // do on the next tick as long as the table does not still think it is there.
761    let name = wire.named();
762    if !name.is_empty() && !wire.inbound {
763        let mut map = server.cluster.map.lock();
764        if let Some(at) = map.find(name.as_bytes()) {
765            map.nodes[usize::from(at)].linked = false;
766        }
767    }
768}
769
770// -------------------------------------------------------------- building packets
771
772/// The fixed header, filled in from this node's view of itself.
773fn header(server: &Server, map: &Map, kind: u16) -> Vec<u8> {
774    let mut p = yo_alloc::allow(|| vec![0u8; HDR_LEN]);
775    p[0..4].copy_from_slice(SIG);
776    put16(&mut p, O_VER, PROTO_VER);
777    put16(&mut p, O_TYPE, kind);
778    put16(&mut p, O_PORT, map.nodes[0].port);
779    put16(&mut p, O_CPORT, map.nodes[0].bus);
780    put16(&mut p, O_PPORT, 0);
781    put16(&mut p, O_FLAGS, map.nodes[0].flags);
782    // A replica sends its master's slots and its master's epoch, flagged as a
783    // replica so nobody mistakes it for the owner. That is how a replica can
784    // answer a gossip round at all without having to say it knows nothing.
785    let speaking = map.nodes[0]
786        .master
787        .filter(|_| map.nodes[0].flags & FLAG_SLAVE != 0)
788        .map_or(0, usize::from);
789    put64(&mut p, O_CURRENT_EPOCH, server.cluster.epoch.load(Relaxed));
790    put64(&mut p, O_CONFIG_EPOCH, map.nodes[speaking].epoch);
791    put64(&mut p, O_OFFSET, server.repl_offset());
792    p[O_SENDER..O_SENDER + NAME_LEN].copy_from_slice(map.nodes[0].id.as_bytes());
793    for slot in 0..SLOTS {
794        if map.owner[slot] == Some(speaking as u16) {
795            set_bit(&mut p[O_SLOTS..O_SLOTS + BITMAP_LEN], slot);
796        }
797    }
798    if let Some(master) = map.nodes[0].master {
799        let id = map.nodes[usize::from(master)].id.as_bytes();
800        p[O_SLAVEOF..O_SLAVEOF + NAME_LEN].copy_from_slice(id);
801    }
802    // The address is left empty on purpose. A node does not know its own address
803    // until somebody connects to it, and the receiver takes it off the socket,
804    // which is the reference's auto discovery and is why a cluster can be built
805    // out of nodes that were never told where they are.
806    let _ = O_MYIP;
807    p[O_STATE] = if server.cluster_up() {
808        STATE_OK
809    } else {
810        STATE_FAIL
811    };
812    p[O_MFLAGS] = MF_EXT_DATA;
813    // A master in the middle of a manual failover says so on everything it
814    // sends, which is what tells the replica that the offset above is the last
815    // one there will ever be.
816    if map.nodes[0].is_master() && server.cluster.manual.end.load(Relaxed) != 0 {
817        p[O_MFLAGS] |= MF_PAUSED;
818    }
819    p
820}
821
822/// Finish a packet by writing the length the header promises.
823fn seal(p: &mut [u8]) {
824    let total = p.len() as u32;
825    p[O_TOTLEN..O_TOTLEN + 4].copy_from_slice(&total.to_be_bytes());
826}
827
828/// A `PING`, `PONG` or `MEET`, with its gossip and its extensions.
829///
830/// `to` is the node it is going to, which is left out of the gossip because
831/// telling somebody about themselves is the one thing they already know.
832fn ping(server: &Server, map: &Map, kind: u16, to: Option<u16>) -> Vec<u8> {
833    let mut p = header(server, map, kind);
834    let now = server.now_ms();
835    // A tenth of the cluster with a floor of three, which is the reference's
836    // rule and is what keeps the packet a fixed size as the cluster grows while
837    // still passing news round in a few rounds.
838    let mut want = (map.nodes.len() / 10).max(3);
839    if map.nodes.len() >= 2 {
840        want = want.min(map.nodes.len() - 2);
841    } else {
842        want = 0;
843    }
844    let mut count = 0u16;
845    let mut sent: Vec<u16> = yo_alloc::allow(|| Vec::with_capacity(want + 4));
846    let mut tries = want * 3;
847    while sent.len() < want && tries > 0 {
848        tries -= 1;
849        let at = pick(map.nodes.len());
850        if at == 0 || Some(at) == to || sent.contains(&at) {
851            continue;
852        }
853        let node = &map.nodes[usize::from(at)];
854        // A node in handshake has a made up name, a node with no address cannot
855        // be reached by whoever hears about it, and a node that is not linked
856        // and owns nothing is one this node is about to forget anyway.
857        if node.flags & (FLAG_HANDSHAKE | FLAG_NOADDR) != 0 {
858            continue;
859        }
860        if !node.linked && map.runs(at).is_empty() {
861            continue;
862        }
863        sent.push(at);
864    }
865    // Everybody this node thinks is down goes on the end whether or not they
866    // were drawn, because a failure report that arrives late is a failover that
867    // happens late.
868    for at in 1..map.nodes.len() as u16 {
869        if map.nodes[usize::from(at)].flags & FLAG_PFAIL != 0 && !sent.contains(&at) {
870            sent.push(at);
871        }
872    }
873    for at in sent {
874        let node = &map.nodes[usize::from(at)];
875        let mut entry = [0u8; GOSSIP_LEN];
876        entry[G_NAME..G_NAME + NAME_LEN].copy_from_slice(node.id.as_bytes());
877        entry[G_PING..G_PING + 4].copy_from_slice(&((node.ping_sent / 1000) as u32).to_be_bytes());
878        entry[G_PONG..G_PONG + 4].copy_from_slice(&((node.pong_recv / 1000) as u32).to_be_bytes());
879        let host = node.host.as_bytes();
880        let take = host.len().min(IP_LEN - 1);
881        entry[G_IP..G_IP + take].copy_from_slice(&host[..take]);
882        entry[G_PORT..G_PORT + 2].copy_from_slice(&node.port.to_be_bytes());
883        entry[G_CPORT..G_CPORT + 2].copy_from_slice(&node.bus.to_be_bytes());
884        entry[G_FLAGS..G_FLAGS + 2].copy_from_slice(&node.flags.to_be_bytes());
885        yo_alloc::allow(|| p.extend_from_slice(&entry));
886        count += 1;
887    }
888    let _ = now;
889    put16(&mut p, O_COUNT, count);
890    let mut exts = 0u16;
891    // The shard id and the secret go on every ping. Both are forty bytes and
892    // neither is optional, which is why a bare ping is never just a header.
893    push_ext(&mut p, X_SHARDID, map.nodes[0].shard.as_bytes());
894    exts += 1;
895    let secret = server.cluster.bus.secret.lock();
896    if secret.len() == NAME_LEN {
897        push_ext(&mut p, X_SECRET, secret.as_bytes());
898        exts += 1;
899    }
900    drop(secret);
901    put16(&mut p, O_EXTENSIONS, exts);
902    seal(&mut p);
903    p
904}
905
906/// Put one extension on the end of a packet, padded to the eight byte boundary
907/// the reference insists on.
908fn push_ext(p: &mut Vec<u8>, kind: u16, data: &[u8]) {
909    let len = 8 + data.len().div_ceil(8) * 8;
910    yo_alloc::allow(|| {
911        p.extend_from_slice(&(len as u32).to_be_bytes());
912        p.extend_from_slice(&kind.to_be_bytes());
913        p.extend_from_slice(&[0, 0]);
914        p.extend_from_slice(data);
915        p.resize(p.len() + (len - 8 - data.len()), 0);
916    });
917}
918
919/// A `FAIL`, which says one node is gone and is believed on sight.
920fn fail_packet(server: &Server, map: &Map, about: &str) -> Vec<u8> {
921    let mut p = header(server, map, T_FAIL);
922    yo_alloc::allow(|| p.extend_from_slice(about.as_bytes()));
923    seal(&mut p);
924    p
925}
926
927/// A `PUBLISH` or `PUBLISHSHARD`, which is how a message reaches a subscriber on
928/// another node.
929fn publish_packet(server: &Server, map: &Map, shard: bool, channel: &[u8], body: &[u8]) -> Vec<u8> {
930    let kind = if shard { T_PUBLISHSHARD } else { T_PUBLISH };
931    let mut p = header(server, map, kind);
932    yo_alloc::allow(|| {
933        p.extend_from_slice(&(channel.len() as u32).to_be_bytes());
934        p.extend_from_slice(&(body.len() as u32).to_be_bytes());
935        p.extend_from_slice(channel);
936        p.extend_from_slice(body);
937    });
938    seal(&mut p);
939    p
940}
941
942/// An `UPDATE`, which is what a node sends back to somebody claiming slots it
943/// knows belong to a newer configuration.
944fn update_packet(server: &Server, map: &Map, about: u16) -> Vec<u8> {
945    let mut p = header(server, map, T_UPDATE);
946    let node = &map.nodes[usize::from(about)];
947    let mut body = [0u8; 8 + NAME_LEN + BITMAP_LEN];
948    body[0..8].copy_from_slice(&node.epoch.to_be_bytes());
949    body[8..8 + NAME_LEN].copy_from_slice(node.id.as_bytes());
950    for slot in 0..SLOTS {
951        if map.owner[slot] == Some(about) {
952            set_bit(&mut body[8 + NAME_LEN..], slot);
953        }
954    }
955    yo_alloc::allow(|| p.extend_from_slice(&body));
956    seal(&mut p);
957    p
958}
959
960// ------------------------------------------------------------ reading packets
961
962/// What one packet asked this node to do, gathered up while the table was
963/// locked and carried out after it was not.
964///
965/// The whole of packet processing runs with the node table locked, because it
966/// reads and writes half of it and a reader that saw it half updated would route
967/// a client wrongly. Nothing that blocks may happen under that lock, so a reply
968/// is built while it is held and written after it is dropped, and that is what
969/// this carries.
970#[derive(Default)]
971struct Todo {
972    /// Packets to write back on the link the packet came in on.
973    reply: Vec<Vec<u8>>,
974    /// Packets to write to everybody.
975    shout: Vec<Vec<u8>>,
976    /// A message that arrived for the local subscribers.
977    deliver: Option<(bool, Vec<u8>, Vec<u8>)>,
978    /// Whether the table is worth writing out again.
979    save: bool,
980    /// Whether the slot coverage needs counting again once the lock is gone.
981    recount: bool,
982    /// Slots this node was serving and is not any more.
983    ///
984    /// Carried out of the lock rather than acted on inside it, because what
985    /// happens to them is a migration finishing and a walk of the keyspace, and
986    /// neither of those is a thing to do while every command on the server is
987    /// waiting on the map.
988    lost: Vec<u16>,
989    /// Whether giving them away left this node following the node that took
990    /// them, which is a node that keeps its keys rather than dropping them.
991    demoted: bool,
992    /// Whether the link should be closed rather than read again.
993    close: bool,
994}
995
996/// Handle one packet, and say whether the link is still worth reading.
997fn process(server: &Arc<Server>, wire: &Arc<Wire>, p: &[u8]) -> bool {
998    if be16(p, O_VER) != PROTO_VER {
999        return true;
1000    }
1001    let kind = be16(p, O_TYPE);
1002    let Some(explen) = expected(p, kind) else {
1003        return true;
1004    };
1005    if explen != p.len() {
1006        return true;
1007    }
1008    let now = server.now_ms();
1009    let mut todo = Todo::default();
1010    {
1011        let mut map = server.cluster.map.lock();
1012        digest(server, wire, p, kind, now, &mut map, &mut todo);
1013    }
1014    for packet in &todo.reply {
1015        wire.send(packet);
1016    }
1017    if !todo.shout.is_empty() {
1018        for link in server.cluster.bus.all() {
1019            for packet in &todo.shout {
1020                link.send(packet);
1021            }
1022        }
1023    }
1024    if let Some((shard, channel, body)) = todo.deliver
1025        && server.anyone_subscribed()
1026    {
1027        let kind = if shard { Kind::Shard } else { Kind::Channel };
1028        pubsub::deliver(server, kind, &channel, &body);
1029    }
1030    if todo.save {
1031        server.cluster.bus.dirty.store(true, Relaxed);
1032    }
1033    if todo.recount {
1034        server.recount_coverage();
1035    }
1036    // Last, and outside the lock. A slot that has gone to somebody else is where
1037    // a migration ends and where the keys behind it stop being this node's, and
1038    // both of those read the map they would otherwise be holding.
1039    server.asm_slots_moved(&todo.lost, todo.demoted);
1040    !todo.close
1041}
1042
1043/// How long a packet of this type should be, or `None` for one that cannot be
1044/// worked out and is therefore not a packet.
1045///
1046/// The reference does this before it looks at anything else and refuses on a
1047/// mismatch rather than reading what it can. That is worth copying exactly: a
1048/// length field that disagrees with the body is the shape of every parser bug
1049/// there has ever been, and the cheapest answer is to not have a parser that
1050/// runs on one.
1051fn expected(p: &[u8], kind: u16) -> Option<usize> {
1052    match kind {
1053        T_PING | T_PONG | T_MEET => {
1054            let count = usize::from(be16(p, O_COUNT));
1055            let mut len = HDR_LEN.checked_add(count.checked_mul(GOSSIP_LEN)?)?;
1056            if p.get(O_MFLAGS).is_some_and(|f| f & MF_EXT_DATA != 0) {
1057                let mut left = be16(p, O_EXTENSIONS);
1058                let mut at = len;
1059                while left > 0 {
1060                    left -= 1;
1061                    let extlen = be32(p, at) as usize;
1062                    if extlen < 8 || !extlen.is_multiple_of(8) || p.len().checked_sub(len)? < extlen
1063                    {
1064                        return None;
1065                    }
1066                    len += extlen;
1067                    at += extlen;
1068                }
1069            }
1070            Some(len)
1071        }
1072        T_FAIL => Some(HDR_LEN + NAME_LEN),
1073        T_PUBLISH | T_PUBLISHSHARD => {
1074            let channel = be32(p, HDR_LEN) as usize;
1075            let body = be32(p, HDR_LEN + 4) as usize;
1076            HDR_LEN
1077                .checked_add(8)?
1078                .checked_add(channel)?
1079                .checked_add(body)
1080        }
1081        T_AUTH_REQUEST | T_AUTH_ACK | T_MFSTART => Some(HDR_LEN),
1082        T_UPDATE => Some(HDR_LEN + 8 + NAME_LEN + BITMAP_LEN),
1083        // A type this node does not handle is well formed by definition, which
1084        // is the reference's own answer and is what lets a newer node talk to an
1085        // older one without either of them dropping the conversation.
1086        _ => Some(p.len()),
1087    }
1088}
1089
1090/// Everything one packet does to the node table.
1091#[allow(clippy::too_many_lines)]
1092fn digest(
1093    server: &Arc<Server>,
1094    wire: &Arc<Wire>,
1095    p: &[u8],
1096    kind: u16,
1097    now: u64,
1098    map: &mut Map,
1099    todo: &mut Todo,
1100) {
1101    let flags = be16(p, O_FLAGS);
1102    let claimed = node_id(p, O_SENDER);
1103    // Who sent it. An outbound link knows without looking, unless the node on
1104    // the other end is still in handshake and therefore still has the made up
1105    // name this node gave it.
1106    let linked = wire.named();
1107    let mut sender = None;
1108    if !linked.is_empty()
1109        && let Some(at) = map.find(linked.as_bytes())
1110        && map.nodes[usize::from(at)].flags & FLAG_HANDSHAKE == 0
1111    {
1112        sender = Some(at);
1113    }
1114    if sender.is_none()
1115        && let Some(id) = claimed.as_deref()
1116    {
1117        sender = map.find(id.as_bytes());
1118        if sender.is_some() && linked.is_empty() {
1119            wire.name(id);
1120        }
1121    }
1122    if let Some(at) = sender {
1123        let node = &mut map.nodes[usize::from(at)];
1124        if p.get(O_MFLAGS).is_some_and(|f| f & MF_EXT_DATA != 0) {
1125            node.flags |= super::FLAG_EXTENSIONS;
1126        }
1127        node.data_recv = now;
1128    }
1129    let sender_epoch = be64(p, O_CONFIG_EPOCH);
1130    if let Some(at) = sender
1131        && map.nodes[usize::from(at)].flags & FLAG_HANDSHAKE == 0
1132    {
1133        let theirs = be64(p, O_CURRENT_EPOCH);
1134        server.cluster.epoch.fetch_max(theirs, Relaxed);
1135        let node = &mut map.nodes[usize::from(at)];
1136        if sender_epoch > node.epoch {
1137            node.epoch = sender_epoch;
1138            todo.save = true;
1139        }
1140        node.offset = be64(p, O_OFFSET);
1141        // A manual failover this node asked for, and the answer to the only
1142        // question it was waiting on: where the master stopped. The first paused
1143        // header is the one that counts, because the ones after it say the same
1144        // thing and taking a later one would only move the target.
1145        let manual = &server.cluster.manual;
1146        if manual.end.load(Relaxed) != 0
1147            && manual.offset.load(Relaxed) == OFFSET_UNKNOWN
1148            && map.nodes[0].flags & FLAG_SLAVE != 0
1149            && map.nodes[0].master == Some(at)
1150            && p.get(O_MFLAGS).is_some_and(|f| f & MF_PAUSED != 0)
1151        {
1152            manual.offset.store(be64(p, O_OFFSET), Relaxed);
1153        }
1154    }
1155
1156    if kind == T_PING || kind == T_MEET {
1157        // A node learns its own address from the socket a MEET arrived on,
1158        // which is the only address in the cluster that is known to be reachable
1159        // from somewhere else. A plain ping is enough when there is no address
1160        // at all yet, because having a wrong one is better than having none and
1161        // a MEET will correct it.
1162        if (kind == T_MEET || map.nodes[0].host.is_empty()) && map.nodes[0].host != wire.local {
1163            yo_alloc::allow(|| map.nodes[0].host.clone_from(&wire.local));
1164            todo.save = true;
1165        }
1166        if sender.is_none() && kind == T_MEET {
1167            // Somebody was told to meet this node. Nothing about them is trusted
1168            // yet beyond where they are, so they go in as a handshake node with
1169            // a name this node made up, and the ping they answer with is what
1170            // replaces it.
1171            let host = {
1172                let announced = text(p, O_MYIP, IP_LEN);
1173                if announced.is_empty() {
1174                    yo_alloc::allow(|| wire.peer.clone())
1175                } else {
1176                    announced
1177                }
1178            };
1179            let id = yo_alloc::allow(|| String::from_utf8_lossy(&new_id()).into_owned());
1180            let node = yo_alloc::allow(|| {
1181                Node::new(
1182                    id,
1183                    host,
1184                    be16(p, O_PORT),
1185                    be16(p, O_CPORT),
1186                    FLAG_HANDSHAKE,
1187                    now,
1188                )
1189            });
1190            yo_alloc::allow(|| map.nodes.push(node));
1191            todo.save = true;
1192            // The gossip on a MEET from a stranger is taken anyway, because the
1193            // type of the packet is the trust: only a node that was told to meet
1194            // this one sends one, and it is worth knowing who else it has met.
1195            gossip(server, p, now, map, todo);
1196        }
1197        todo.reply.push(ping(server, map, T_PONG, sender));
1198    }
1199
1200    match kind {
1201        T_PING | T_PONG | T_MEET => {}
1202        T_FAIL => {
1203            if sender.is_some()
1204                && let Some(id) = node_id(p, HDR_LEN)
1205                && let Some(at) = map.find(id.as_bytes())
1206                && map.nodes[usize::from(at)].flags & (FLAG_FAIL | FLAG_MYSELF) == 0
1207            {
1208                let node = &mut map.nodes[usize::from(at)];
1209                node.flags |= FLAG_FAIL;
1210                node.flags &= !FLAG_PFAIL;
1211                node.fail_time = now;
1212                todo.save = true;
1213            }
1214            return;
1215        }
1216        T_PUBLISH | T_PUBLISHSHARD => {
1217            if sender.is_none() {
1218                todo.close = true;
1219                return;
1220            }
1221            let channel = be32(p, HDR_LEN) as usize;
1222            let body = be32(p, HDR_LEN + 4) as usize;
1223            let at = HDR_LEN + 8;
1224            todo.deliver = yo_alloc::allow(|| {
1225                Some((
1226                    kind == T_PUBLISHSHARD,
1227                    p[at..at + channel].to_vec(),
1228                    p[at + channel..at + channel + body].to_vec(),
1229                ))
1230            });
1231            return;
1232        }
1233        T_UPDATE => {
1234            if sender.is_none() {
1235                todo.close = true;
1236                return;
1237            }
1238            let epoch = be64(p, HDR_LEN);
1239            let Some(id) = node_id(p, HDR_LEN + 8) else {
1240                return;
1241            };
1242            let Some(about) = map.find(id.as_bytes()) else {
1243                return;
1244            };
1245            if epoch <= map.nodes[usize::from(about)].epoch {
1246                return;
1247            }
1248            map.nodes[usize::from(about)].epoch = epoch;
1249            map.nodes[usize::from(about)].flags &= !FLAG_SLAVE;
1250            map.nodes[usize::from(about)].flags |= FLAG_MASTER;
1251            map.nodes[usize::from(about)].master = None;
1252            claim_slots(
1253                server,
1254                map,
1255                about,
1256                epoch,
1257                &p[HDR_LEN + 8 + NAME_LEN..],
1258                todo,
1259            );
1260            todo.save = true;
1261            return;
1262        }
1263        T_AUTH_REQUEST => {
1264            // A vote is only ever given to a node this one knows, because the
1265            // whole question is about a master this node has an opinion on.
1266            if let Some(at) = sender
1267                && vote_if_needed(server, map, at, p, now)
1268            {
1269                let mut packet = header(server, map, T_AUTH_ACK);
1270                seal(&mut packet);
1271                yo_alloc::allow(|| todo.reply.push(packet));
1272                todo.save = true;
1273            }
1274            return;
1275        }
1276        T_AUTH_ACK => {
1277            // Only a master serving slots has a vote to give, and only a vote
1278            // cast in the epoch this node is standing in counts. The second
1279            // check is what stops a late reply to a previous election being
1280            // counted towards this one.
1281            let vote = &server.cluster.vote;
1282            if let Some(at) = sender
1283                && map.nodes[usize::from(at)].is_master()
1284                && !map.runs(at).is_empty()
1285                && be64(p, O_CURRENT_EPOCH) >= vote.epoch.load(Relaxed)
1286            {
1287                vote.count.fetch_add(1, Relaxed);
1288            }
1289            return;
1290        }
1291        T_MFSTART => {
1292            if let Some(at) = sender {
1293                stand_down(server, map, at, now, todo);
1294            }
1295            return;
1296        }
1297        // Modules are not a thing here at all.
1298        T_MODULE => return,
1299        _ => return,
1300    }
1301
1302    // From here down is the config half of a PING, PONG or MEET, which is where
1303    // a cluster actually agrees on anything.
1304    if !wire.inbound {
1305        let held = map.find(linked.as_bytes());
1306        if let Some(at) = held
1307            && map.nodes[usize::from(at)].flags & FLAG_HANDSHAKE != 0
1308        {
1309            match sender {
1310                // This node had already met them under their real name, so the
1311                // handshake node is a duplicate and goes away.
1312                Some(known) => {
1313                    let host = yo_alloc::allow(|| wire.peer.clone());
1314                    let node = &mut map.nodes[usize::from(known)];
1315                    if node.host != host {
1316                        node.host = host;
1317                        node.port = be16(p, O_PORT);
1318                        node.bus = be16(p, O_CPORT);
1319                    }
1320                    map.forget(at);
1321                    todo.save = true;
1322                    todo.close = true;
1323                    return;
1324                }
1325                // The handshake worked. The made up name is replaced with the
1326                // real one and the node is an ordinary node from here on.
1327                None => {
1328                    let Some(id) = claimed.clone() else {
1329                        return;
1330                    };
1331                    wire.name(&id);
1332                    let node = &mut map.nodes[usize::from(at)];
1333                    yo_alloc::allow(|| node.id = id);
1334                    node.flags &= !(FLAG_HANDSHAKE | FLAG_MEET);
1335                    node.flags |= flags & (FLAG_MASTER | FLAG_SLAVE);
1336                    node.pong_recv = now;
1337                    node.ping_sent = 0;
1338                    sender = Some(at);
1339                    todo.save = true;
1340                }
1341            }
1342        } else if let Some(at) = held
1343            && Some(map.nodes[usize::from(at)].id.as_str()) != claimed.as_deref()
1344        {
1345            // Somebody else is answering on the address this node had written
1346            // down for a peer. The address is wrong rather than the peer, so the
1347            // peer keeps its identity and loses its address until gossip finds
1348            // it again.
1349            let node = &mut map.nodes[usize::from(at)];
1350            node.flags |= FLAG_NOADDR;
1351            node.host.clear();
1352            node.port = 0;
1353            node.bus = 0;
1354            node.linked = false;
1355            todo.save = true;
1356            todo.close = true;
1357            return;
1358        }
1359    }
1360
1361    let Some(at) = sender else {
1362        return;
1363    };
1364    // The no failover flag is the sender's to set and everybody else's to
1365    // believe, because it is the sender saying whether it wants to be promoted.
1366    let node = &mut map.nodes[usize::from(at)];
1367    node.flags &= !FLAG_NOFAILOVER;
1368    node.flags |= flags & FLAG_NOFAILOVER;
1369    if kind == T_PING && !wire.inbound {
1370        let host = yo_alloc::allow(|| wire.peer.clone());
1371        if node.host != host {
1372            node.host = host;
1373            node.port = be16(p, O_PORT);
1374            node.bus = be16(p, O_CPORT);
1375            todo.save = true;
1376        }
1377    }
1378    if !wire.inbound && kind == T_PONG {
1379        node.pong_recv = now;
1380        node.ping_sent = 0;
1381        if node.flags & FLAG_PFAIL != 0 {
1382            node.flags &= !FLAG_PFAIL;
1383            todo.save = true;
1384        } else if node.flags & FLAG_FAIL != 0 {
1385            clear_failure(map, at, now);
1386            todo.save = true;
1387        }
1388    }
1389
1390    // Master or replica, which has to settle before the slots are looked at
1391    // because a replica's slot claim is its master's and means something else.
1392    let follows = node_id(p, O_SLAVEOF);
1393    match follows {
1394        None => {
1395            if map.nodes[usize::from(at)].flags & FLAG_SLAVE != 0 {
1396                let node = &mut map.nodes[usize::from(at)];
1397                node.flags &= !FLAG_SLAVE;
1398                node.flags |= FLAG_MASTER;
1399                node.master = None;
1400                todo.save = true;
1401            }
1402        }
1403        Some(id) => {
1404            let master = map.find(id.as_bytes());
1405            if map.nodes[usize::from(at)].is_master() {
1406                // A master that has become a replica. When its new master is in
1407                // the same shard this is the tail of a failover, so the slots
1408                // move rather than vanish, and the new master is promoted here
1409                // to match. When it is not, the node has been moved to another
1410                // shard and its slots are simply not its any more.
1411                let same_shard = master.is_some_and(|m| {
1412                    map.nodes[usize::from(m)].shard == map.nodes[usize::from(at)].shard
1413                });
1414                if same_shard && sender_epoch >= map.nodes[usize::from(at)].epoch {
1415                    let m = master.expect("same shard means there is one");
1416                    for slot in 0..SLOTS {
1417                        if map.owner[slot] == Some(at) {
1418                            map.owner[slot] = Some(m);
1419                        }
1420                    }
1421                    let promoted = &mut map.nodes[usize::from(m)];
1422                    promoted.flags &= !FLAG_SLAVE;
1423                    promoted.flags |= FLAG_MASTER;
1424                    promoted.master = None;
1425                    promoted.epoch = sender_epoch;
1426                } else if !same_shard {
1427                    for slot in 0..SLOTS {
1428                        if map.owner[slot] == Some(at) {
1429                            map.owner[slot] = None;
1430                        }
1431                    }
1432                }
1433                let node = &mut map.nodes[usize::from(at)];
1434                node.flags &= !(FLAG_MASTER | FLAG_MIGRATE_TO);
1435                node.flags |= FLAG_SLAVE;
1436                todo.save = true;
1437            }
1438            if let Some(m) = master
1439                && map.nodes[usize::from(at)].master != Some(m)
1440                && m != at
1441            {
1442                map.nodes[usize::from(at)].master = Some(m);
1443                let shard = yo_alloc::allow(|| map.nodes[usize::from(m)].shard.clone());
1444                yo_alloc::allow(|| map.nodes[usize::from(at)].shard = shard);
1445                todo.save = true;
1446            }
1447        }
1448    }
1449
1450    // The slots. Only a master's claim counts, and only when it differs from
1451    // what this node already had, which is one memcmp in front of a walk of
1452    // sixteen thousand slots and is worth having.
1453    let speaking = if map.nodes[usize::from(at)].is_master() {
1454        Some(at)
1455    } else {
1456        map.nodes[usize::from(at)].master
1457    };
1458    let claim = &p[O_SLOTS..O_SLOTS + BITMAP_LEN];
1459    let dirty = speaking
1460        .is_some_and(|m| (0..SLOTS).any(|slot| bit(claim, slot) != (map.owner[slot] == Some(m))));
1461    if dirty && map.nodes[usize::from(at)].is_master() {
1462        claim_slots(server, map, at, sender_epoch, claim, todo);
1463    }
1464    if dirty {
1465        // The other way round: the sender is claiming slots this node knows have
1466        // moved on to somebody with a newer epoch, so it is told about the first
1467        // one of them and works the rest out from there.
1468        for slot in 0..SLOTS {
1469            if !bit(claim, slot) {
1470                continue;
1471            }
1472            let Some(owner) = map.owner[slot] else {
1473                continue;
1474            };
1475            if owner == at {
1476                continue;
1477            }
1478            if map.nodes[usize::from(owner)].epoch > sender_epoch {
1479                todo.reply.push(update_packet(server, map, owner));
1480                break;
1481            }
1482        }
1483    }
1484    // Two masters with the same epoch cannot both be right, so the one with the
1485    // smaller id gives way by taking a new one. Deterministic and needs no
1486    // agreement, which is the only kind of tiebreak that works in a partition.
1487    if map.nodes[0].is_master()
1488        && map.nodes[usize::from(at)].is_master()
1489        && sender_epoch == map.nodes[0].epoch
1490        && map.nodes[0].id < map.nodes[usize::from(at)].id
1491    {
1492        let next = server.cluster.epoch.fetch_add(1, Relaxed) + 1;
1493        map.nodes[0].epoch = next;
1494        todo.save = true;
1495    }
1496    gossip(server, p, now, map, todo);
1497    extensions(server, p, now, map, at, todo);
1498}
1499
1500/// The gossip section, which is what everybody else looks like from where the
1501/// sender is standing.
1502fn gossip(server: &Arc<Server>, p: &[u8], now: u64, map: &mut Map, todo: &mut Todo) {
1503    let count = usize::from(be16(p, O_COUNT));
1504    let sender_master = node_id(p, O_SENDER)
1505        .and_then(|id| map.find(id.as_bytes()))
1506        .is_none_or(|at| map.nodes[usize::from(at)].is_master());
1507    for entry in 0..count {
1508        let base = HDR_LEN + entry * GOSSIP_LEN;
1509        let Some(id) = node_id(p, base + G_NAME) else {
1510            continue;
1511        };
1512        let flags = be16(p, base + G_FLAGS);
1513        let host = text(p, base + G_IP, IP_LEN);
1514        let port = be16(p, base + G_PORT);
1515        let bus = be16(p, base + G_CPORT);
1516        if let Some(at) = map.find(id.as_bytes()) {
1517            if at == 0 {
1518                continue;
1519            }
1520            // A master saying somebody is down is a vote; anybody else saying it
1521            // is an opinion. Both are recorded, and only the votes are counted.
1522            if sender_master {
1523                let sender = node_id(p, O_SENDER).unwrap_or_default();
1524                if flags & (FLAG_FAIL | FLAG_PFAIL) != 0 {
1525                    report(map, at, &sender, now);
1526                    if mark_failing(map, at, now) {
1527                        let about = yo_alloc::allow(|| map.nodes[usize::from(at)].id.clone());
1528                        todo.shout.push(fail_packet(server, map, &about));
1529                        todo.save = true;
1530                    }
1531                } else {
1532                    unreport(map, at, &sender);
1533                }
1534            }
1535            let node = &mut map.nodes[usize::from(at)];
1536            if node.flags & (FLAG_FAIL | FLAG_PFAIL) == 0
1537                && node.ping_sent == 0
1538                && node.reports.is_empty()
1539            {
1540                // The sender heard from them more recently than this node did, so
1541                // take their word for when. The half second ceiling is the
1542                // reference's guard against a peer whose clock is ahead.
1543                let heard = u64::from(be32(p, base + G_PONG)) * 1000;
1544                if heard > node.pong_recv && heard <= now + 500 {
1545                    node.pong_recv = heard;
1546                }
1547            } else if node.down()
1548                && flags & (FLAG_FAIL | FLAG_PFAIL | FLAG_NOADDR | FLAG_HANDSHAKE) == 0
1549                && !host.is_empty()
1550                && (node.host != host || node.port != port)
1551            {
1552                // Down here and up there, at an address this node does not have.
1553                // The address is the thing that is wrong, so it is replaced and
1554                // the next tick tries again.
1555                yo_alloc::allow(|| node.host = host);
1556                node.port = port;
1557                node.bus = bus;
1558                node.linked = false;
1559                node.flags &= !FLAG_NOADDR;
1560                todo.save = true;
1561            }
1562            continue;
1563        }
1564        // Somebody new. Taken only from a sender this node already knows, and
1565        // only when the id is not one that was just forgotten on purpose.
1566        //
1567        // It goes in under the id and the flags the gossip carried rather than
1568        // as a handshake, which is the difference between learning about a node
1569        // and meeting one. A handshake exists to find out an id that is not
1570        // known yet, and here it is: the sender said it. Adding it as a
1571        // handshake instead would mean opening a link to an address whose owner
1572        // might have changed, which is how a node ends up in somebody else's
1573        // cluster.
1574        if flags & FLAG_NOADDR != 0 {
1575            continue;
1576        }
1577        if server.cluster.bus.blacklisted(&id, now) {
1578            continue;
1579        }
1580        let flags = flags & !(FLAG_MYSELF | FLAG_HANDSHAKE | FLAG_MEET);
1581        let node = yo_alloc::allow(|| Node::new(id, host, port, bus, flags, now));
1582        yo_alloc::allow(|| map.nodes.push(node));
1583        todo.save = true;
1584    }
1585}
1586
1587/// The extensions on the end of a ping.
1588fn extensions(server: &Arc<Server>, p: &[u8], now: u64, map: &mut Map, at: u16, todo: &mut Todo) {
1589    if !p.get(O_MFLAGS).is_some_and(|f| f & MF_EXT_DATA != 0) {
1590        return;
1591    }
1592    let mut left = be16(p, O_EXTENSIONS);
1593    let mut base = HDR_LEN + usize::from(be16(p, O_COUNT)) * GOSSIP_LEN;
1594    while left > 0 && base + 8 <= p.len() {
1595        left -= 1;
1596        let extlen = be32(p, base) as usize;
1597        if extlen < 8 || base + extlen > p.len() {
1598            return;
1599        }
1600        let kind = be16(p, base + 4);
1601        let data = &p[base + 8..base + extlen];
1602        match kind {
1603            X_SHARDID => {
1604                let id = String::from_utf8_lossy(&data[..NAME_LEN.min(data.len())]);
1605                if id.len() == NAME_LEN && map.nodes[usize::from(at)].shard != id {
1606                    yo_alloc::allow(|| map.nodes[usize::from(at)].shard = id.into_owned());
1607                    todo.save = true;
1608                }
1609            }
1610            X_SECRET => {
1611                // The whole cluster ends up on the smallest secret anybody
1612                // started with, which needs no leader to decide and settles in
1613                // one gossip round.
1614                let theirs = String::from_utf8_lossy(&data[..NAME_LEN.min(data.len())]);
1615                let mut mine = server.cluster.bus.secret.lock();
1616                if theirs.len() == NAME_LEN && **mine > *theirs {
1617                    yo_alloc::allow(|| *mine = theirs.into_owned());
1618                }
1619            }
1620            X_FORGOTTEN => {
1621                // Somebody has been forgotten on purpose. Forget them here too,
1622                // and refuse to learn them again for as long as the sender says,
1623                // which is what stops the rest of the cluster putting them back.
1624                if data.len() < NAME_LEN + 8 {
1625                    return;
1626                }
1627                let Some(id) = node_id(data, 0) else {
1628                    return;
1629                };
1630                let ttl = be64(data, NAME_LEN);
1631                if map.nodes[0].id == id
1632                    || map.nodes[0].master.map(usize::from)
1633                        == map.find(id.as_bytes()).map(usize::from)
1634                {
1635                    base += extlen;
1636                    continue;
1637                }
1638                server.cluster.bus.blacklist(&id, now + ttl);
1639                if let Some(gone) = map.find(id.as_bytes())
1640                    && gone != 0
1641                {
1642                    server.cluster.bus.cut(&id);
1643                    map.forget(gone);
1644                    todo.save = true;
1645                }
1646            }
1647            // The hostname and the human readable name are carried for the
1648            // benefit of an operator reading `CLUSTER NODES` on a real server,
1649            // and nothing here routes on either of them.
1650            X_HOSTNAME | X_HUMAN_NAME => {}
1651            _ => {}
1652        }
1653        base += extlen;
1654    }
1655}
1656
1657/// Record that somebody thinks a node is down.
1658fn report(map: &mut Map, at: u16, from: &str, now: u64) {
1659    if from.is_empty() {
1660        return;
1661    }
1662    let node = &mut map.nodes[usize::from(at)];
1663    if let Some(held) = node.reports.iter_mut().find(|(who, _)| who == from) {
1664        held.1 = now;
1665        return;
1666    }
1667    yo_alloc::allow(|| node.reports.push((String::from(from), now)));
1668}
1669
1670/// Take one back, which is somebody saying they can reach a node after all.
1671fn unreport(map: &mut Map, at: u16, from: &str) {
1672    map.nodes[usize::from(at)]
1673        .reports
1674        .retain(|(who, _)| who != from);
1675}
1676
1677/// Whether enough of the cluster agrees that a node is gone, and flag it if so.
1678///
1679/// The quorum is a majority of the masters that are serving slots, which is the
1680/// same electorate a failover vote is counted against, and this node counts
1681/// itself when it is one of them. Reports older than twice the node timeout are
1682/// dropped first, so a node that flickered a long time ago does not help
1683/// condemn one that is flickering now.
1684fn mark_failing(map: &mut Map, at: u16, now: u64) -> bool {
1685    let cutoff = now.saturating_sub(NODE_TIMEOUT_MS * 2);
1686    map.nodes[usize::from(at)]
1687        .reports
1688        .retain(|(_, when)| *when > cutoff);
1689    if map.nodes[usize::from(at)].flags & (FLAG_PFAIL | FLAG_FAIL) == 0 {
1690        return false;
1691    }
1692    if map.nodes[usize::from(at)].flags & FLAG_FAIL != 0 {
1693        return false;
1694    }
1695    let needed = map.voters() / 2 + 1;
1696    let mut votes = map.nodes[usize::from(at)].reports.len();
1697    if map.nodes[0].is_master() && !map.runs(0).is_empty() {
1698        votes += 1;
1699    }
1700    if votes < needed {
1701        return false;
1702    }
1703    let node = &mut map.nodes[usize::from(at)];
1704    node.flags &= !FLAG_PFAIL;
1705    node.flags |= FLAG_FAIL;
1706    node.fail_time = now;
1707    true
1708}
1709
1710/// Undo a failure verdict, which is only allowed for a replica that came back or
1711/// for a master that came back still owning nothing.
1712///
1713/// A master that comes back owning slots is not cleared, because the cluster has
1714/// probably promoted its replica by now and clearing it would leave two nodes
1715/// claiming the same slots. It stays failed until it hears about the promotion
1716/// and stands down on its own.
1717fn clear_failure(map: &mut Map, at: u16, now: u64) {
1718    let node = &map.nodes[usize::from(at)];
1719    let replica = !node.is_master();
1720    let empty = map.runs(at).is_empty();
1721    let stale = now.saturating_sub(node.fail_time) > NODE_TIMEOUT_MS * 2;
1722    if replica || empty || stale {
1723        let node = &mut map.nodes[usize::from(at)];
1724        node.flags &= !FLAG_FAIL;
1725        node.fail_time = 0;
1726    }
1727}
1728
1729/// Take a master's word for which slots are its.
1730///
1731/// This is the one place a slot changes hands without an operator asking, so it
1732/// is careful about which claims it believes. A slot nobody owns is taken on
1733/// sight. A slot owned by somebody with an older epoch changes hands, because a
1734/// higher epoch is the cluster's way of saying this configuration is newer. A
1735/// slot this node is importing is left alone, because an import in progress is
1736/// an operator's decision and outranks gossip. And a slot this node loses while
1737/// still holding keys for it is remembered, because those keys now belong to
1738/// somebody else and keeping them would mean two nodes answering for the same
1739/// data.
1740fn claim_slots(
1741    server: &Arc<Server>,
1742    map: &mut Map,
1743    owner: u16,
1744    epoch: u64,
1745    claim: &[u8],
1746    todo: &mut Todo,
1747) {
1748    // Whose slots decide where this node belongs afterwards. A master answers
1749    // for its own and a replica answers for its master's, because a replica of a
1750    // master that has just lost everything is a replica of nothing and is how a
1751    // second replica of a failed master finds the one that replaced it.
1752    let ours = if map.nodes[0].is_master() {
1753        Some(0)
1754    } else {
1755        map.nodes[0].master
1756    };
1757    let mut lost = 0usize;
1758    for slot in 0..SLOTS {
1759        if !bit(claim, slot) {
1760            continue;
1761        }
1762        if map.owner[slot] == Some(owner) || map.importing[slot].is_some() {
1763            continue;
1764        }
1765        let held = map.owner[slot];
1766        let newer = held.is_none_or(|at| map.nodes[usize::from(at)].epoch <= epoch);
1767        if !newer {
1768            continue;
1769        }
1770        if held == ours {
1771            lost += 1;
1772        }
1773        if held == Some(0) {
1774            yo_alloc::allow(|| todo.lost.push(slot as u16));
1775        }
1776        map.owner[slot] = Some(owner);
1777        map.migrating[slot] = None;
1778        todo.save = true;
1779    }
1780    // A master that has just given away its last slot is not a master any more.
1781    // Following the node that took them is what a real server does and is what
1782    // makes a failed master come back as a replica of whoever replaced it.
1783    if lost > 0 && ours.is_some_and(|at| map.runs(at).is_empty()) && owner != 0 {
1784        todo.demoted = true;
1785        // Whoever took them is the node this one was standing down for, if it
1786        // was standing down at all, so the pause it armed goes now rather than
1787        // when the clock runs out.
1788        manual_reset(server);
1789        map.nodes[0].flags &= !FLAG_MASTER;
1790        map.nodes[0].flags |= FLAG_SLAVE;
1791        map.nodes[0].master = Some(owner);
1792        let shard = yo_alloc::allow(|| map.nodes[usize::from(owner)].shard.clone());
1793        yo_alloc::allow(|| map.nodes[0].shard = shard);
1794        let (host, port) = {
1795            let node = &map.nodes[usize::from(owner)];
1796            (yo_alloc::allow(|| node.host.clone()), node.port)
1797        };
1798        let following = Arc::clone(server);
1799        spawn("yo-bus-follow", move || {
1800            following.follow_master(&host, port);
1801        });
1802    }
1803    // The coverage count is not touched here on purpose. It reads the same map
1804    // this runs under, and the lock is not reentrant, so the caller does it
1805    // once the lock is gone.
1806    todo.recount = true;
1807}
1808
1809// ------------------------------------------------------------ the failover vote
1810
1811/// Answer a replica asking to be promoted, if every condition holds.
1812///
1813/// This is the reference's `clusterSendFailoverAuthIfNeeded` and the order of
1814/// the checks is its order, because the order is the safety. A master gets one
1815/// vote per epoch and gives it to the first replica that asks, and everything
1816/// in front of that is about making sure the question was a fair one to ask.
1817///
1818/// Nothing is sent back when a condition fails. There is no such thing as a no
1819/// vote on this protocol: a replica counts the yeses it got and gives up when
1820/// the election times out, which means a master that has crashed and a master
1821/// that disapproves look the same from where the replica is standing. That is
1822/// deliberate, since the alternative is a reply that a replica could be made to
1823/// wait for.
1824fn vote_if_needed(server: &Arc<Server>, map: &mut Map, at: u16, p: &[u8], now: u64) -> bool {
1825    // Only a master serving a slot has a vote, because the electorate is the
1826    // masters that serve slots and nothing else would make the quorum add up.
1827    if map.nodes[0].flags & FLAG_SLAVE != 0 || map.runs(0).is_empty() {
1828        return false;
1829    }
1830    // The asking node's epoch cannot be behind this node's. It cannot really be
1831    // ahead either, since reading the packet has already pulled this node's
1832    // epoch up to it, so what this catches is a request that was already stale
1833    // when it arrived.
1834    let epoch = server.cluster.epoch.load(Relaxed);
1835    if be64(p, O_CURRENT_EPOCH) < epoch {
1836        return false;
1837    }
1838    // One vote per epoch, and it has already gone.
1839    if server.cluster.vote.given.load(Relaxed) == epoch {
1840        return false;
1841    }
1842    // It has to be a replica, this node has to know whose, and that master has
1843    // to be one the cluster has given up on. A manual failover is the exception
1844    // and says so in the packet, because there the master is up and is in on it.
1845    let asking = &map.nodes[usize::from(at)];
1846    let Some(master) = asking.master.filter(|_| asking.flags & FLAG_SLAVE != 0) else {
1847        return false;
1848    };
1849    let forced = p.get(O_MFLAGS).is_some_and(|f| f & MF_FORCEACK != 0);
1850    if map.nodes[usize::from(master)].flags & FLAG_FAIL == 0 && !forced {
1851        return false;
1852    }
1853    // Not twice about the same master inside two node timeouts. A second replica
1854    // of the same master asking straight after the first is either the first one
1855    // having failed to win or two of them racing, and in both cases the answer
1856    // that keeps the shard with one master is to wait and see how the first one
1857    // went.
1858    if now.saturating_sub(map.nodes[usize::from(master)].voted_time) < NODE_TIMEOUT_MS * 2 {
1859        return false;
1860    }
1861    // The slots it is claiming have to be ones it would be claiming under an
1862    // epoch at least as new as whoever is serving them here. A replica asking to
1863    // take over slots that have already moved somewhere newer is a replica that
1864    // has been out of touch, and voting for it would undo the move.
1865    let claimed = be64(p, O_CONFIG_EPOCH);
1866    for slot in 0..SLOTS {
1867        if !bit(&p[O_SLOTS..O_SLOTS + BITMAP_LEN], slot) {
1868            continue;
1869        }
1870        if map.owner[slot].is_some_and(|held| map.nodes[usize::from(held)].epoch > claimed) {
1871            return false;
1872        }
1873    }
1874    server.cluster.vote.given.store(epoch, Relaxed);
1875    map.nodes[usize::from(master)].voted_time = now;
1876    true
1877}
1878
1879/// How many replicas of the same master hold more data than this node does.
1880///
1881/// The reference's `clusterGetSlaveRank`, and the offsets it compares are the
1882/// ones the other replicas put in their own packets rather than anything asked
1883/// for, so a rank is always a little out of date and that is fine: it decides a
1884/// delay and not an outcome.
1885fn rank_of(map: &Map, master: u16, mine: u64) -> u64 {
1886    map.nodes
1887        .iter()
1888        .skip(1)
1889        .filter(|node| {
1890            node.master == Some(master)
1891                && node.flags & FLAG_SLAVE != 0
1892                && node.flags & FLAG_NOFAILOVER == 0
1893                && node.offset > mine
1894        })
1895        .count() as u64
1896}
1897
1898/// What the cron has to do about the election, worked out under the lock.
1899enum Step {
1900    /// Nothing, which is the answer on nearly every tick of nearly every node.
1901    Idle,
1902    /// The delay has just been worked out, so tell the other replicas of this
1903    /// master how far this node has got in case it changes their minds.
1904    Announce,
1905    /// Ask every node for a vote.
1906    Ask(Vec<u8>),
1907    /// The quorum is in and the slots are this node's now.
1908    Won,
1909}
1910
1911/// Work out what this tick of the election does, under the map lock.
1912///
1913/// The reference's `clusterHandleSlaveFailover`. Every branch of it returns and
1914/// waits for the next tick rather than carrying on, which is what makes the
1915/// whole thing readable: the state is in one place and each tick moves it at
1916/// most one step.
1917fn decide(server: &Arc<Server>, map: &mut Map, now: u64) -> Step {
1918    let vote = &server.cluster.vote;
1919    let manual = &server.cluster.manual;
1920    // A manual failover is one somebody asked for on this node, and once it is
1921    // ready it is allowed three things an automatic one is not: it does not need
1922    // the master to be gone, it ignores the flag that says this node would
1923    // rather not stand, and it does not care how far behind the data is. All
1924    // three are safe for the same reason, which is that the master is holding
1925    // its clients still and this node has caught up with everything it wrote.
1926    let asked = manual.end.load(Relaxed) != 0;
1927    let ready = asked && manual.can_start.load(Relaxed);
1928    // A replica of a master the cluster has given up on, which is willing to be
1929    // promoted, and whose master was serving something worth taking over.
1930    let me = &map.nodes[0];
1931    if me.flags & FLAG_SLAVE == 0 || (me.flags & FLAG_NOFAILOVER != 0 && !ready) {
1932        return Step::Idle;
1933    }
1934    let Some(master) = me.master else {
1935        return Step::Idle;
1936    };
1937    if map.nodes[usize::from(master)].flags & FLAG_FAIL == 0 && !ready {
1938        return Step::Idle;
1939    }
1940    if map.runs(master).is_empty() {
1941        return Step::Idle;
1942    }
1943    // How far out of touch with the master this node was before it died. The
1944    // node timeout comes off because that much silence is what made it dead in
1945    // the first place and is not the replica's fault.
1946    if !ready && server.master_silence(now).saturating_sub(NODE_TIMEOUT_MS) > STALE_DATA_MS {
1947        return Step::Idle;
1948    }
1949    let since = now as i64 - vote.at.load(Relaxed) as i64;
1950    if since > (ELECTION_TIMEOUT_MS * 2) as i64 {
1951        // Nothing running, or the last one is long enough ago to try again. The
1952        // delay is a fixed part, a random part and a part per replica that holds
1953        // more data than this one. None of that applies to a manual failover:
1954        // there is nothing to let propagate, nobody else is standing, and the
1955        // operator is waiting, so it goes now and at the front of the queue.
1956        let rank = if asked {
1957            0
1958        } else {
1959            rank_of(map, master, server.repl_offset())
1960        };
1961        let at = if asked {
1962            now
1963        } else {
1964            now + ELECTION_DELAY_MS
1965                + u64::from(pick(ELECTION_DELAY_MS as usize))
1966                + rank * RANK_DELAY_MS
1967        };
1968        vote.at.store(at, Relaxed);
1969        vote.rank.store(rank, Relaxed);
1970        vote.count.store(0, Relaxed);
1971        vote.sent.store(false, Relaxed);
1972        return Step::Announce;
1973    }
1974    if !vote.sent.load(Relaxed) {
1975        // Another replica may have said something since the delay was worked
1976        // out. Falling further down the order pushes the delay back, and
1977        // climbing it does not pull it forward, which is the reference's rule
1978        // and is what keeps two replicas swapping places from both asking at
1979        // once. Not done on a manual failover, where the delay is nought and
1980        // there is no order to fall down.
1981        if !asked {
1982            let rank = rank_of(map, master, server.repl_offset());
1983            let was = vote.rank.load(Relaxed);
1984            if rank > was {
1985                vote.at.fetch_add((rank - was) * RANK_DELAY_MS, Relaxed);
1986                vote.rank.store(rank, Relaxed);
1987            }
1988        }
1989        if now < vote.at.load(Relaxed) {
1990            return Step::Idle;
1991        }
1992    }
1993    if since > ELECTION_TIMEOUT_MS as i64 {
1994        // Too late to be worth counting. The retry window above is what starts
1995        // the next one.
1996        return Step::Idle;
1997    }
1998    if !vote.sent.load(Relaxed) {
1999        let epoch = server.cluster.epoch.fetch_add(1, Relaxed) + 1;
2000        vote.epoch.store(epoch, Relaxed);
2001        vote.sent.store(true, Relaxed);
2002        let mut packet = header(server, map, T_AUTH_REQUEST);
2003        // The master is up and is in on it, so say so, or every master asked
2004        // would refuse on the grounds that there is nothing wrong with it.
2005        if asked {
2006            packet[O_MFLAGS] |= MF_FORCEACK;
2007        }
2008        seal(&mut packet);
2009        return Step::Ask(packet);
2010    }
2011    if vote.count.load(Relaxed) < (map.size() / 2 + 1) as u64 {
2012        return Step::Idle;
2013    }
2014    let epoch = vote.epoch.load(Relaxed);
2015    replace_master(map, master, epoch);
2016    Step::Won
2017}
2018
2019/// Take everything the master was serving, under an epoch nobody else has used.
2020///
2021/// The reference's `clusterFailoverReplaceYourMaster` as far as the table goes,
2022/// and the epoch is what makes every other node believe this over whatever it
2023/// had written down. The caller has already made sure of the epoch, either by
2024/// winning an election under it or by bumping it on its own.
2025fn replace_master(map: &mut Map, master: u16, epoch: u64) {
2026    if map.nodes[0].epoch < epoch {
2027        map.nodes[0].epoch = epoch;
2028    }
2029    map.nodes[0].flags &= !FLAG_SLAVE;
2030    map.nodes[0].flags |= FLAG_MASTER;
2031    map.nodes[0].master = None;
2032    for slot in 0..SLOTS {
2033        if map.owner[slot] == Some(master) {
2034            map.owner[slot] = Some(0);
2035        }
2036    }
2037}
2038
2039/// The half of taking over that cannot be done while the table is locked.
2040fn won(server: &Arc<Server>) {
2041    server.stop_following();
2042    manual_reset(server);
2043    server.recount_coverage();
2044    server.cluster.bus.dirty.store(true, Relaxed);
2045    let _ = super::save(server);
2046    server.cluster_broadcast_pong();
2047}
2048
2049/// Stand for election when the master is gone, and take over on winning.
2050fn failover(server: &Arc<Server>, now: u64) {
2051    let step = {
2052        let mut map = server.cluster.map.lock();
2053        decide(server, &mut map, now)
2054    };
2055    match step {
2056        Step::Idle => {}
2057        // The reference sends this to the other replicas of the same master and
2058        // this sends it to everybody, which is a packet more per node on a
2059        // cluster that has just lost one and is the same answer.
2060        Step::Announce => server.cluster_broadcast_pong(),
2061        Step::Ask(packet) => {
2062            for link in server.cluster.bus.all() {
2063                link.send(&packet);
2064            }
2065            server.cluster.bus.dirty.store(true, Relaxed);
2066        }
2067        Step::Won => won(server),
2068    }
2069}
2070
2071// ------------------------------------------------------- the manual failover
2072
2073/// Forget any manual failover, lifting the pause if this node armed one.
2074///
2075/// The reference's `resetManualFailover`, and it is called on every way out of
2076/// one: the timeout, the takeover, winning, and being stood down by the node
2077/// that replaced this one. A master that is left holding a pause it armed for a
2078/// failover that never happened is the one outcome worth going out of the way to
2079/// avoid, since from a client it looks exactly like the server having stopped.
2080fn manual_reset(server: &Server) {
2081    let manual = &server.cluster.manual;
2082    let held = manual.held.swap(0, Relaxed);
2083    if held != 0 {
2084        server.lift(held, false);
2085    }
2086    manual.end.store(0, Relaxed);
2087    manual.can_start.store(false, Relaxed);
2088    manual.offset.store(OFFSET_UNKNOWN, Relaxed);
2089}
2090
2091/// A replica has asked this node to stand down, which is the reference's
2092/// `MFSTART` arm and is the whole of the master's part in a manual failover.
2093///
2094/// It stops taking writes and says where it stopped, and everything after that
2095/// is the replica's problem. The pause is what makes the whole thing worth
2096/// having: without it the replica would be chasing an offset that kept moving
2097/// and would either never catch up or take over having missed something.
2098fn stand_down(server: &Arc<Server>, map: &Map, at: u16, now: u64, todo: &mut Todo) {
2099    // Only from one of this node's own replicas, because holding every client
2100    // on this server still is a large thing to be talked into and the only node
2101    // it helps is one that is about to replace this one.
2102    let asking = &map.nodes[usize::from(at)];
2103    if asking.master != Some(0) || asking.flags & FLAG_SLAVE == 0 || !map.nodes[0].is_master() {
2104        return;
2105    }
2106    // A slot migration and a failover both decide who owns a slot, and running
2107    // them at once is the one way to end up with two answers. The migration is
2108    // the one that gets dropped, because it can be started again and a failover
2109    // that is already under way cannot.
2110    server.cluster.asm.cancel(None, now as i64);
2111    manual_reset(server);
2112    let manual = &server.cluster.manual;
2113    manual.end.store(now + MANUAL_TIMEOUT_MS, Relaxed);
2114    let until = now + MANUAL_TIMEOUT_MS * MANUAL_PAUSE_MULT;
2115    manual.held.store(until, Relaxed);
2116    server.pause(until, false);
2117    // Answered at once rather than left to the cron, because the ping carries
2118    // the offset the writes stopped at and that is the only thing the replica
2119    // is waiting for.
2120    yo_alloc::allow(|| todo.reply.push(ping(server, map, T_PING, Some(at))));
2121}
2122
2123/// Move a manual failover along by one tick, on whichever side of it this is.
2124///
2125/// The reference's `manualFailoverCheckTimeout` and `clusterHandleManualFailover`
2126/// in one, since they run one after the other and share every condition. All the
2127/// replica is waiting for is its own offset to reach the one the master stopped
2128/// at, and all the master is waiting for is somebody to take its slots off it or
2129/// the clock to run out.
2130fn manual_cron(server: &Arc<Server>, now: u64) {
2131    let manual = &server.cluster.manual;
2132    let end = manual.end.load(Relaxed);
2133    if end == 0 {
2134        return;
2135    }
2136    if end < now {
2137        manual_reset(server);
2138        return;
2139    }
2140    if manual.can_start.load(Relaxed) {
2141        return;
2142    }
2143    let offset = manual.offset.load(Relaxed);
2144    if offset != OFFSET_UNKNOWN && offset == server.repl_offset() {
2145        // Everything the master wrote is here, and nothing more is coming. This
2146        // is the moment a manual failover is safe, and it is the only moment,
2147        // which is why the whole handshake exists.
2148        manual.can_start.store(true, Relaxed);
2149    }
2150}
2151
2152/// `CLUSTER FAILOVER [FORCE|TAKEOVER]`, which is the reference's checks and then
2153/// one of its three ways of going about it.
2154///
2155/// The plain form asks the master to hold its clients still and waits for the
2156/// two offsets to meet, which is the only form that cannot lose a write. `FORCE`
2157/// skips the asking, which is for a master that is up but not answering, and
2158/// loses whatever it had not sent yet. `TAKEOVER` skips the election as well and
2159/// simply says this node owns the slots now under an epoch it made up, which is
2160/// for a cluster that has lost too many masters to hold an election at all.
2161pub(super) fn manual_failover(
2162    server: &Arc<Server>,
2163    force: bool,
2164    takeover: bool,
2165) -> Result<(), Error> {
2166    let now = server.now_ms();
2167    let mut ask: Option<(String, Vec<u8>)> = None;
2168    let mut promoted = false;
2169    {
2170        let mut map = server.cluster.map.lock();
2171        if map.nodes[0].is_master() {
2172            return Err(Error::new(
2173                Code::Invalid,
2174                "You should send CLUSTER FAILOVER to a replica",
2175            ));
2176        }
2177        let Some(master) = map.nodes[0].master else {
2178            return Err(Error::new(
2179                Code::Invalid,
2180                "I'm a replica but my master is unknown to me",
2181            ));
2182        };
2183        let node = &map.nodes[usize::from(master)];
2184        if !force && (node.flags & FLAG_FAIL != 0 || !node.linked) {
2185            return Err(Error::new(
2186                Code::Invalid,
2187                "Master is down or failed, please use CLUSTER FAILOVER FORCE",
2188            ));
2189        }
2190        manual_reset(server);
2191        server
2192            .cluster
2193            .manual
2194            .end
2195            .store(now + MANUAL_TIMEOUT_MS, Relaxed);
2196        if takeover {
2197            super::bump_without_consensus(server, &mut map);
2198            let epoch = map.nodes[0].epoch;
2199            replace_master(&mut map, master, epoch);
2200            promoted = true;
2201        } else if force {
2202            server.cluster.manual.can_start.store(true, Relaxed);
2203        } else {
2204            let mut packet = header(server, &map, T_MFSTART);
2205            seal(&mut packet);
2206            let id = yo_alloc::allow(|| map.nodes[usize::from(master)].id.clone());
2207            ask = Some((id, packet));
2208        }
2209    }
2210    if promoted {
2211        won(server);
2212    }
2213    if let Some((id, packet)) = ask
2214        && let Some(link) = server.cluster.bus.outbound(&id)
2215    {
2216        link.send(&packet);
2217    }
2218    Ok(())
2219}
2220
2221// ---------------------------------------------------------------- the cron
2222
2223/// The bus's own clock, which is where everything that is not a reply happens.
2224fn cron(server: &Arc<Server>) {
2225    let mut tick = 0u64;
2226    loop {
2227        std::thread::sleep(Duration::from_millis(CRON_MS));
2228        tick += 1;
2229        let now = server.now_ms();
2230        // Who needs a link, who needs a ping, and who has been quiet too long.
2231        // All decided under the lock and all carried out after it, because a
2232        // connect takes half a second in the worst case and the routing path
2233        // reads this table on every command.
2234        let mut dial_list: Vec<(String, String, u16, bool)> = Vec::new();
2235        let mut ping_list: Vec<(String, Vec<u8>)> = Vec::new();
2236        let mut shout: Vec<Vec<u8>> = Vec::new();
2237        let mut follow: Option<(String, u16)> = None;
2238        let mut save = false;
2239        let paused = server.cluster.manual.held.load(Relaxed) != 0;
2240        {
2241            let mut map = server.cluster.map.lock();
2242            let count = map.nodes.len();
2243            for at in 1..count as u16 {
2244                let node = &map.nodes[usize::from(at)];
2245                // A handshake that never completed is a node that is not there.
2246                if node.flags & FLAG_HANDSHAKE != 0
2247                    && now.saturating_sub(node.data_recv) > NODE_TIMEOUT_MS.max(1000)
2248                {
2249                    map.forget(at);
2250                    save = true;
2251                    break;
2252                }
2253                if node.flags & FLAG_NOADDR != 0 || node.host.is_empty() {
2254                    continue;
2255                }
2256                if !node.linked {
2257                    // Only a node this one was told to meet hears MEET, because
2258                    // MEET is the packet that says trust me, I am not in another
2259                    // cluster. Everything else is a plain ping, including a node
2260                    // in handshake that was met the other way round.
2261                    let meet = node.flags & FLAG_MEET != 0;
2262                    yo_alloc::allow(|| {
2263                        dial_list.push((node.id.clone(), node.host.clone(), node.bus, meet));
2264                    });
2265                    continue;
2266                }
2267                // A ping every second, or sooner for whoever this node has heard
2268                // from least recently out of five, which is the reference's way
2269                // of getting round a cluster in far fewer than N rounds.
2270                let quiet = now.saturating_sub(node.pong_recv);
2271                let due = node.ping_sent == 0 && quiet > PING_MS;
2272                // A master holding its clients still for a manual failover pings
2273                // its replicas on every tick instead of every second, because the
2274                // replica cannot move until it has seen a header saying the
2275                // writes have stopped and where, and a second of that is a second
2276                // of a server nobody can write to.
2277                let waiting = paused && node.master == Some(0);
2278                if due
2279                    || waiting
2280                    || (tick.is_multiple_of(10) && oldest_of_five(&map, now) == Some(at))
2281                {
2282                    let packet = ping(server, &map, T_PING, Some(at));
2283                    let id = yo_alloc::allow(|| map.nodes[usize::from(at)].id.clone());
2284                    map.nodes[usize::from(at)].ping_sent = now;
2285                    ping_list.push((id, packet));
2286                }
2287            }
2288            // Anybody who has not answered in time is possibly failed, which is
2289            // this node's opinion and becomes the cluster's once enough masters
2290            // share it.
2291            for at in 1..map.nodes.len() as u16 {
2292                let node = &map.nodes[usize::from(at)];
2293                if node.flags & (FLAG_HANDSHAKE | FLAG_FAIL | FLAG_PFAIL) != 0 {
2294                    continue;
2295                }
2296                let waiting = if node.ping_sent == 0 {
2297                    0
2298                } else {
2299                    now.saturating_sub(node.ping_sent)
2300                };
2301                let quiet = now.saturating_sub(node.data_recv);
2302                if waiting.min(quiet) > NODE_TIMEOUT_MS {
2303                    map.nodes[usize::from(at)].flags |= FLAG_PFAIL;
2304                    save = true;
2305                }
2306                if mark_failing(&mut map, at, now) {
2307                    let about = yo_alloc::allow(|| map.nodes[usize::from(at)].id.clone());
2308                    shout.push(fail_packet(server, &map, &about));
2309                    save = true;
2310                }
2311            }
2312            // A node whose table says it is a replica but which is not following
2313            // anybody starts following. That is how a replica comes back after a
2314            // restart, since the node table is on disk and the replication link
2315            // is not, and it is also how one that was told to replicate a node
2316            // it had no address for yet gets going once the address turns up.
2317            if map.nodes[0].flags & FLAG_SLAVE != 0
2318                && !server.following()
2319                && let Some(master) = map.nodes[0].master
2320                && let Some(node) = map.nodes.get(usize::from(master))
2321                && node.flags & FLAG_NOADDR == 0
2322                && !node.host.is_empty()
2323            {
2324                follow = yo_alloc::allow(|| Some((node.host.clone(), node.port)));
2325            }
2326        }
2327        // Called here and not on a thread of its own, because it starts the
2328        // replica thread and returns, and doing it here is what makes the guard
2329        // above true again before the next tick rather than a tick later.
2330        if let Some((host, port)) = follow {
2331            server.follow_master(&host, port);
2332        }
2333        for (id, host, bus, meet) in dial_list {
2334            if !dial(server, &id, &host, bus, meet) {
2335                continue;
2336            }
2337            let mut map = server.cluster.map.lock();
2338            if let Some(at) = map.find(id.as_bytes()) {
2339                map.nodes[usize::from(at)].linked = true;
2340            }
2341        }
2342        for (id, packet) in ping_list {
2343            if let Some(link) = server.cluster.bus.outbound(&id) {
2344                link.send(&packet);
2345            } else {
2346                // The link went between deciding to ping and sending it, so the
2347                // node is dialled again on the next tick. The ping is left
2348                // standing rather than taken back, because it is what failure
2349                // detection measures and a node that cannot be sent a ping is
2350                // exactly the node that should be running out of time.
2351                let mut map = server.cluster.map.lock();
2352                if let Some(at) = map.find(id.as_bytes()) {
2353                    map.nodes[usize::from(at)].linked = false;
2354                }
2355            }
2356        }
2357        if !shout.is_empty() {
2358            for link in server.cluster.bus.all() {
2359                for packet in &shout {
2360                    link.send(packet);
2361                }
2362            }
2363        }
2364        if save {
2365            server.cluster.bus.dirty.store(true, Relaxed);
2366        }
2367        server.recount_coverage();
2368        manual_cron(server, now);
2369        failover(server, now);
2370        server.asm_cron();
2371        server.asm_relax();
2372        // The file is written at most ten times a second and only when something
2373        // moved, which keeps a busy cluster from writing it on every packet.
2374        if tick.is_multiple_of(10) && server.cluster.bus.dirty.swap(false, Relaxed) {
2375            let _ = super::save(server);
2376        }
2377    }
2378}
2379
2380/// Whoever this node has heard from least recently, out of five drawn at random.
2381///
2382/// Five and not all of them because the point is to bias the ping order towards
2383/// the nodes that need one without walking the table every tenth of a second.
2384fn oldest_of_five(map: &Map, now: u64) -> Option<u16> {
2385    if map.nodes.len() < 2 {
2386        return None;
2387    }
2388    let mut best: Option<(u16, u64)> = None;
2389    for _ in 0..5 {
2390        let at = pick(map.nodes.len());
2391        if at == 0 {
2392            continue;
2393        }
2394        let node = &map.nodes[usize::from(at)];
2395        if node.ping_sent != 0 || node.flags & (FLAG_HANDSHAKE | FLAG_NOADDR) != 0 {
2396            continue;
2397        }
2398        let quiet = now.saturating_sub(node.pong_recv);
2399        if best.is_none_or(|(_, held)| quiet > held) {
2400            best = Some((at, quiet));
2401        }
2402    }
2403    best.map(|(at, _)| at)
2404}
2405
2406// ------------------------------------------------------- what the commands do
2407
2408impl Server {
2409    /// Start a handshake with a node at an address, which is `CLUSTER MEET`.
2410    ///
2411    /// Nothing is known about them yet, not even their id, so they go into the
2412    /// table under a name this node made up and the next tick opens a link and
2413    /// sends them a MEET. Their answer carries their real id, which replaces the
2414    /// made up one. That is why meeting a node twice is harmless and why meeting
2415    /// one that is already known is a no-op rather than a duplicate.
2416    pub(super) fn cluster_meet(&self, host: &str, port: u16, bus: u16) {
2417        let now = self.now_ms();
2418        let mut map = self.cluster.map.lock();
2419        let known = map
2420            .nodes
2421            .iter()
2422            .any(|node| node.host == host && node.port == port);
2423        if known {
2424            return;
2425        }
2426        let id = yo_alloc::allow(|| String::from_utf8_lossy(&new_id()).into_owned());
2427        let node = yo_alloc::allow(|| {
2428            Node::new(
2429                id,
2430                yo_alloc::allow(|| String::from(host)),
2431                port,
2432                bus,
2433                FLAG_HANDSHAKE | FLAG_MEET,
2434                now,
2435            )
2436        });
2437        yo_alloc::allow(|| map.nodes.push(node));
2438    }
2439
2440    /// Whether an id was forgotten on purpose recently, which is what makes
2441    /// forgetting the same node twice answer OK rather than complain.
2442    pub(super) fn cluster_blacklisted(&self, id: &str) -> bool {
2443        self.cluster.bus.blacklisted(id, self.now_ms())
2444    }
2445
2446    /// Drop a node and tell everybody else to, which is `CLUSTER FORGET`.
2447    ///
2448    /// The telling is the part that matters. Dropping a node on its own would
2449    /// last until the next gossip packet from anybody who still had it, so the
2450    /// id is refused for a minute here and the refusal is passed round in the
2451    /// extension that carries it.
2452    pub(super) fn cluster_forget(&self, at: u16) {
2453        let now = self.now_ms();
2454        let id = {
2455            let mut map = self.cluster.map.lock();
2456            let id = yo_alloc::allow(|| map.nodes[usize::from(at)].id.clone());
2457            map.forget(at);
2458            id
2459        };
2460        self.cluster.bus.blacklist(&id, now);
2461        self.cluster.bus.cut(&id);
2462        let packet = {
2463            let map = self.cluster.map.lock();
2464            let mut p = ping(self, &map, T_PING, None);
2465            // The forgotten node rides on the next ping rather than in a packet
2466            // of its own, which is the reference's design: there is no reliable
2467            // delivery on the bus, so a fact that has to reach everybody is
2468            // repeated rather than sent once.
2469            let mut body = [0u8; NAME_LEN + 8];
2470            body[..NAME_LEN].copy_from_slice(id.as_bytes());
2471            body[NAME_LEN..].copy_from_slice(&BLACKLIST_MS.to_be_bytes());
2472            push_ext(&mut p, X_FORGOTTEN, &body);
2473            let exts = be16(&p, O_EXTENSIONS) + 1;
2474            put16(&mut p, O_EXTENSIONS, exts);
2475            seal(&mut p);
2476            p
2477        };
2478        for link in self.cluster.bus.all() {
2479            link.send(&packet);
2480        }
2481        self.cluster.bus.dirty.store(true, Relaxed);
2482    }
2483
2484    /// Become a replica of another node, which is `CLUSTER REPLICATE`.
2485    pub(super) fn cluster_replicate(self: &Arc<Server>, at: u16) {
2486        // A node that has just been told whose replica it is has no business
2487        // still holding a manual failover open, and if it armed a pause for one
2488        // that pause goes with it.
2489        manual_reset(self);
2490        let (host, port) = {
2491            let mut map = self.cluster.map.lock();
2492            // Whatever slots this node was holding are not its any more, which
2493            // is the reference's rule and is why the command refuses when there
2494            // are keys in them.
2495            for slot in 0..SLOTS {
2496                if map.owner[slot] == Some(0) {
2497                    map.owner[slot] = None;
2498                }
2499            }
2500            map.nodes[0].flags &= !(FLAG_MASTER | FLAG_MIGRATE_TO);
2501            map.nodes[0].flags |= FLAG_SLAVE;
2502            map.nodes[0].master = Some(at);
2503            let shard = yo_alloc::allow(|| map.nodes[usize::from(at)].shard.clone());
2504            yo_alloc::allow(|| map.nodes[0].shard = shard);
2505            let node = &map.nodes[usize::from(at)];
2506            (yo_alloc::allow(|| node.host.clone()), node.port)
2507        };
2508        self.recount_coverage();
2509        self.cluster.bus.dirty.store(true, Relaxed);
2510        if !host.is_empty() {
2511            self.follow_master(&host, port);
2512        }
2513    }
2514
2515    /// Send a published message to every other node, which is what makes a
2516    /// subscriber on one node hear a publish on another.
2517    ///
2518    /// Every node gets a copy of an ordinary publish, because an ordinary
2519    /// subscription is not tied to a slot and could be anywhere. A shard publish
2520    /// only needs to reach the shard that owns the slot, but the reference
2521    /// broadcasts it too and lets the far side drop it, so this does the same.
2522    pub(crate) fn cluster_publish(&self, shard: bool, channel: &[u8], body: &[u8]) {
2523        if !self.cluster_enabled() || !self.cluster.bus.on.load(Relaxed) {
2524            return;
2525        }
2526        let packet = {
2527            let map = self.cluster.map.lock();
2528            publish_packet(self, &map, shard, channel, body)
2529        };
2530        for link in self.cluster.bus.all() {
2531            link.send(&packet);
2532        }
2533    }
2534
2535    /// Send everybody a `PONG` right now rather than waiting for the cron.
2536    ///
2537    /// A `PONG` nobody asked for is how the reference tells the cluster about a
2538    /// configuration change it has just made to itself, and the only thing that
2539    /// makes it a `PONG` rather than a `PING` is that nobody is expected to
2540    /// answer it. What the far side actually reads is the header, which carries
2541    /// this node's slots and its config epoch, so one packet is the whole of the
2542    /// announcement.
2543    ///
2544    /// It matters after a slot import because the epoch has just gone up and the
2545    /// rest of the cluster is still pointing clients at the node the slot came
2546    /// from. Waiting the ordinary ping interval would leave every client that
2547    /// asked the wrong node being redirected to a node that no longer owns it.
2548    pub(super) fn cluster_broadcast_pong(&self) {
2549        if !self.cluster_enabled() || !self.cluster.bus.on.load(Relaxed) {
2550            return;
2551        }
2552        let packet = {
2553            let map = self.cluster.map.lock();
2554            ping(self, &map, T_PONG, None)
2555        };
2556        for link in self.cluster.bus.all() {
2557            link.send(&packet);
2558        }
2559    }
2560
2561    /// `CLUSTER LINKS`, which is one map per open link in each direction.
2562    pub(super) fn cluster_links(&self, out: &mut Out) {
2563        let links = self.cluster.bus.all();
2564        let at = out.len();
2565        let mut n = 0;
2566        for link in links {
2567            let node = link.named();
2568            // The reference only lists links it has associated with a node, and
2569            // an inbound link stays unassociated until a packet on it says who
2570            // is sending, so a connection that has said nothing is not a link
2571            // yet as far as this report is concerned.
2572            if node.is_empty() {
2573                continue;
2574            }
2575            out.map(6);
2576            out.bulk(b"direction");
2577            out.bulk(if link.inbound {
2578                b"from".as_slice()
2579            } else {
2580                b"to".as_slice()
2581            });
2582            out.bulk(b"node");
2583            out.bulk(node.as_bytes());
2584            out.bulk(b"create-time");
2585            out.int(link.created as i64);
2586            out.bulk(b"events");
2587            out.bulk(b"r");
2588            out.bulk(b"send-buffer-allocated");
2589            out.int(link.sent.load(Relaxed) as i64);
2590            out.bulk(b"send-buffer-used");
2591            out.int(0);
2592            n += 1;
2593        }
2594        out.close_array(at, n);
2595    }
2596}
2597
2598#[cfg(test)]
2599mod tests {
2600    use super::*;
2601
2602    #[test]
2603    fn a_bitmap_round_trips_through_the_reference_bit_order() {
2604        let mut bitmap = [0u8; BITMAP_LEN];
2605        for slot in [0usize, 1, 7, 8, 1234, 5061, 12182, SLOTS - 1] {
2606            set_bit(&mut bitmap, slot);
2607        }
2608        for slot in 0..SLOTS {
2609            let want = matches!(slot, 0 | 1 | 7 | 8 | 1234 | 5061 | 12182) || slot == SLOTS - 1;
2610            assert_eq!(bit(&bitmap, slot), want, "slot {slot}");
2611        }
2612        // Least significant bit first inside each byte, which is the one detail
2613        // a reader is likely to get backwards and the one the reference will not
2614        // forgive.
2615        assert_eq!(bitmap[0], 0b1000_0011);
2616        assert_eq!(bitmap[1], 0b0000_0001);
2617    }
2618
2619    #[test]
2620    fn an_extension_is_padded_to_the_eight_byte_boundary() {
2621        let mut p = Vec::new();
2622        push_ext(&mut p, X_SHARDID, &[b'a'; 40]);
2623        assert_eq!(p.len(), 48);
2624        assert_eq!(be32(&p, 0), 48);
2625        assert_eq!(be16(&p, 4), X_SHARDID);
2626        // A hostname is not a multiple of eight and has to be rounded up, which
2627        // is what `getAlignedPingExtSize` does.
2628        let mut q = Vec::new();
2629        push_ext(&mut q, X_HOSTNAME, b"node1.example\0");
2630        assert_eq!(q.len(), 8 + 16);
2631        assert_eq!(be32(&q, 0), 24);
2632    }
2633
2634    #[test]
2635    fn a_packet_of_the_wrong_length_is_refused() {
2636        let mut p = vec![0u8; HDR_LEN];
2637        p[0..4].copy_from_slice(SIG);
2638        put16(&mut p, O_VER, PROTO_VER);
2639        put16(&mut p, O_TYPE, T_PING);
2640        put16(&mut p, O_COUNT, 0);
2641        p[O_MFLAGS] = 0;
2642        seal(&mut p);
2643        assert_eq!(expected(&p, T_PING), Some(HDR_LEN));
2644        // One gossip entry claimed and none present is the shape every parser
2645        // bug has, so it has to come out as a length that does not match.
2646        put16(&mut p, O_COUNT, 1);
2647        assert_eq!(expected(&p, T_PING), Some(HDR_LEN + GOSSIP_LEN));
2648        assert_ne!(expected(&p, T_PING), Some(p.len()));
2649    }
2650
2651    /// A node table with a master that is about to fail, one replica of it and
2652    /// two other masters, which is the smallest cluster an election means
2653    /// anything on.
2654    ///
2655    /// Node 0 is this server and is the replica standing for election. Node 1 is
2656    /// its master and owns the first third of the slots, and nodes 2 and 3 own
2657    /// the rest, so the quorum is two and this node is not part of it.
2658    /// A wall clock reading, since every span in an election is measured
2659    /// against one and a node that has just started is not two node timeouts
2660    /// away from the epoch.
2661    const T0: u64 = 1_700_000_000_000;
2662
2663    fn shard() -> Arc<Server> {
2664        let mut server = Server::new();
2665        server.enable_cluster("", 7000);
2666        let server = Arc::new(server);
2667        let master = server.cluster_pretend_node("1".repeat(40).as_str(), "10.0.0.1", 7001);
2668        let other = server.cluster_pretend_node("2".repeat(40).as_str(), "10.0.0.2", 7002);
2669        let third = server.cluster_pretend_node("3".repeat(40).as_str(), "10.0.0.3", 7003);
2670        server.cluster_pretend_follower(master);
2671        {
2672            let mut map = server.cluster.map.lock();
2673            for slot in 0..SLOTS {
2674                map.owner[slot] = Some(match slot {
2675                    0..=5460 => master,
2676                    5461..=10922 => other,
2677                    _ => third,
2678                });
2679            }
2680        }
2681        server.recount_coverage();
2682        server
2683    }
2684
2685    /// An `AUTH_REQUEST` as a replica of node 1 would send it.
2686    fn asking(epoch: u64, config: u64, forced: bool) -> Vec<u8> {
2687        let mut p = vec![0u8; HDR_LEN];
2688        put64(&mut p, O_CURRENT_EPOCH, epoch);
2689        put64(&mut p, O_CONFIG_EPOCH, config);
2690        for slot in 0..=5460 {
2691            set_bit(&mut p[O_SLOTS..O_SLOTS + BITMAP_LEN], slot);
2692        }
2693        p[O_MFLAGS] = if forced { MF_FORCEACK } else { 0 };
2694        p
2695    }
2696
2697    /// A node that cannot be dialled has to start running out of time, or the
2698    /// election it should be losing never happens.
2699    ///
2700    /// Failure detection measures the time since a ping went out, and a node
2701    /// with no link never gets one sent, so the address that stops answering is
2702    /// the one case where the clock has to be started by hand.
2703    #[test]
2704    fn a_node_that_cannot_be_reached_is_treated_as_pinged() {
2705        let server = shard();
2706        let id = "1".repeat(40);
2707        assert_eq!(server.cluster.map.lock().nodes[1].ping_sent, 0);
2708        unreachable(&server, &id);
2709        let first = server.cluster.map.lock().nodes[1].ping_sent;
2710        assert!(first > 0, "the clock is running");
2711        // And the next failed dial leaves it where it is, because the span that
2712        // matters is the one since the node went quiet and not the one since
2713        // the last attempt to reach it.
2714        unreachable(&server, &id);
2715        assert_eq!(server.cluster.map.lock().nodes[1].ping_sent, first);
2716        // A name nobody knows is not an error, it is a node that has been
2717        // forgotten between the decision to dial it and the attempt.
2718        unreachable(&server, &"9".repeat(40));
2719    }
2720
2721    /// Every reason a master has for not answering a replica that wants its
2722    /// master's slots, in the order a real server checks them.
2723    ///
2724    /// The order is the safety rather than a detail of the implementation, so
2725    /// each one is arranged to be the only thing wrong.
2726    #[test]
2727    fn a_vote_is_given_once_and_only_when_every_condition_holds() {
2728        let server = shard();
2729        // Stand this node up as a master serving the last third, and put a
2730        // replica of node 1 in the table for it to be asked about.
2731        {
2732            let mut map = server.cluster.map.lock();
2733            map.nodes[0].flags &= !FLAG_SLAVE;
2734            map.nodes[0].flags |= FLAG_MASTER;
2735            map.nodes[0].master = None;
2736            for slot in 10923..SLOTS {
2737                map.owner[slot] = Some(0);
2738            }
2739            let mut replica = Node::new(
2740                "4".repeat(40),
2741                "10.0.0.4".to_owned(),
2742                7004,
2743                7004 + 10000,
2744                FLAG_SLAVE,
2745                0,
2746            );
2747            replica.master = Some(1);
2748            map.nodes.push(replica);
2749        }
2750        let at = 4u16;
2751        let ask = |server: &Arc<Server>, p: &[u8], now: u64| {
2752            let mut map = server.cluster.map.lock();
2753            vote_if_needed(server, &mut map, at, p, now)
2754        };
2755        // A replica bumps the epoch before it asks and reading the packet pulls
2756        // this node's up to it, so by the time the question is put the two
2757        // agree and neither is nought.
2758        server.cluster.epoch.store(1, Relaxed);
2759
2760        // The master it wants to replace is up and nobody said this was a manual
2761        // failover, so there is nothing to vote about.
2762        assert!(!ask(&server, &asking(1, 0, false), T0));
2763        // A manual failover says so in the packet, and that is the whole
2764        // difference from where the voter is standing.
2765        assert!(ask(&server, &asking(1, 0, true), T0));
2766        // One vote per epoch, and it has gone.
2767        assert!(!ask(&server, &asking(1, 0, true), T0));
2768
2769        // Give up on node 1 and move the epoch on, which is what a real replica
2770        // would have done before asking again.
2771        server.cluster.epoch.store(2, Relaxed);
2772        {
2773            let mut map = server.cluster.map.lock();
2774            map.nodes[1].flags |= FLAG_FAIL;
2775        }
2776        // Not twice about the same master inside two node timeouts, however
2777        // dead it is, because the first replica may still be winning.
2778        assert!(!ask(&server, &asking(2, 0, false), T0 + NODE_TIMEOUT_MS));
2779        let later = T0 + NODE_TIMEOUT_MS * 2 + 1;
2780        // A request that was stale before it arrived.
2781        assert!(!ask(&server, &asking(1, 0, false), later));
2782        // A node that is not a replica has no master to replace.
2783        {
2784            let mut map = server.cluster.map.lock();
2785            map.nodes[4].flags &= !FLAG_SLAVE;
2786        }
2787        assert!(!ask(&server, &asking(2, 0, false), later));
2788        {
2789            let mut map = server.cluster.map.lock();
2790            map.nodes[4].flags |= FLAG_SLAVE;
2791        }
2792        // Slots that have already moved somewhere newer than the epoch the
2793        // replica would claim them under. Voting for that would undo the move.
2794        {
2795            let mut map = server.cluster.map.lock();
2796            map.owner[3000] = Some(2);
2797            map.nodes[2].epoch = 7;
2798        }
2799        assert!(!ask(&server, &asking(2, 6, false), later));
2800        // The same request under an epoch that is not behind is fine.
2801        assert!(ask(&server, &asking(2, 7, false), later));
2802        assert_eq!(server.cluster.vote.given(), 2);
2803
2804        // And a node with no slots of its own is not part of the electorate at
2805        // all, however much it knows about the shard.
2806        server.cluster.epoch.store(3, Relaxed);
2807        {
2808            let mut map = server.cluster.map.lock();
2809            for slot in 0..SLOTS {
2810                if map.owner[slot] == Some(0) {
2811                    map.owner[slot] = Some(3);
2812                }
2813            }
2814        }
2815        assert!(!ask(
2816            &server,
2817            &asking(3, 7, false),
2818            later + NODE_TIMEOUT_MS * 3
2819        ));
2820    }
2821
2822    /// A replica of a master the cluster has given up on waits its turn, asks
2823    /// once, and takes the slots over when the quorum is in.
2824    #[test]
2825    fn an_election_waits_then_asks_then_wins() {
2826        let server = shard();
2827        let step = |server: &Arc<Server>, now: u64| {
2828            let mut map = server.cluster.map.lock();
2829            decide(server, &mut map, now)
2830        };
2831
2832        // The master is up, so there is no election to hold.
2833        assert!(matches!(step(&server, T0), Step::Idle));
2834        {
2835            let mut map = server.cluster.map.lock();
2836            map.nodes[1].flags |= FLAG_FAIL;
2837        }
2838        // The first tick after that works out when this node may ask and tells
2839        // the other replicas how far it has got.
2840        assert!(matches!(step(&server, T0), Step::Announce));
2841        let at = server.cluster.vote.at.load(Relaxed);
2842        assert!(
2843            (T0 + 500..=T0 + 1000).contains(&at),
2844            "half a second plus up to half a second more, got {at}"
2845        );
2846        // Until then there is nothing to do.
2847        assert!(matches!(step(&server, at - 1), Step::Idle));
2848
2849        // A replica that turns out to hold more data than this one pushes the
2850        // turn back by a second, and one that falls behind does not pull it
2851        // forward again.
2852        {
2853            let mut map = server.cluster.map.lock();
2854            let mut ahead = Node::new(
2855                "5".repeat(40),
2856                "10.0.0.5".to_owned(),
2857                7005,
2858                7005 + 10000,
2859                FLAG_SLAVE,
2860                0,
2861            );
2862            ahead.master = Some(1);
2863            ahead.offset = 900;
2864            map.nodes.push(ahead);
2865        }
2866        assert!(matches!(step(&server, at), Step::Idle));
2867        assert_eq!(server.cluster.vote.at.load(Relaxed), at + RANK_DELAY_MS);
2868        {
2869            let mut map = server.cluster.map.lock();
2870            map.nodes[4].offset = 0;
2871        }
2872        assert!(matches!(step(&server, at), Step::Idle));
2873        assert_eq!(server.cluster.vote.at.load(Relaxed), at + RANK_DELAY_MS);
2874
2875        // Then it asks, once, under an epoch of its own.
2876        let now = at + RANK_DELAY_MS;
2877        let Step::Ask(packet) = step(&server, now) else {
2878            panic!("the turn has come");
2879        };
2880        assert_eq!(be64(&packet, O_CURRENT_EPOCH), 1);
2881        assert_eq!(server.cluster.vote.epoch.load(Relaxed), 1);
2882        // The slots in the request are the master's, because those are the ones
2883        // the answer is about.
2884        assert!(bit(&packet[O_SLOTS..O_SLOTS + BITMAP_LEN], 5460));
2885        assert!(!bit(&packet[O_SLOTS..O_SLOTS + BITMAP_LEN], 5461));
2886        assert!(matches!(step(&server, now), Step::Idle), "asked already");
2887
2888        // One vote out of the three masters is not a quorum.
2889        server.cluster.vote.count.store(1, Relaxed);
2890        assert!(matches!(step(&server, now), Step::Idle));
2891        server.cluster.vote.count.store(2, Relaxed);
2892        assert!(matches!(step(&server, now), Step::Won));
2893
2894        let map = server.cluster.map.lock();
2895        assert!(map.nodes[0].is_master());
2896        assert_eq!(map.nodes[0].master, None);
2897        assert_eq!(map.nodes[0].epoch, 1, "the epoch it stood under");
2898        assert_eq!(map.owner[0], Some(0));
2899        assert_eq!(map.owner[5460], Some(0));
2900        assert_eq!(map.owner[5461], Some(2), "somebody else's slots are theirs");
2901    }
2902
2903    /// An election this node has no business holding is not held.
2904    #[test]
2905    fn a_replica_that_should_not_stand_does_not() {
2906        let refused = |now: u64, set: fn(&Arc<Server>)| {
2907            let server = shard();
2908            {
2909                let mut map = server.cluster.map.lock();
2910                map.nodes[1].flags |= FLAG_FAIL;
2911            }
2912            set(&server);
2913            let mut map = server.cluster.map.lock();
2914            matches!(decide(&server, &mut map, now), Step::Idle)
2915        };
2916        // A master does not stand for election, whatever has happened to
2917        // anybody else.
2918        assert!(refused(T0, |server| {
2919            let mut map = server.cluster.map.lock();
2920            map.nodes[0].flags &= !FLAG_SLAVE;
2921            map.nodes[0].flags |= FLAG_MASTER;
2922        }));
2923        // A replica that has been told not to.
2924        assert!(refused(T0, |server| {
2925            let mut map = server.cluster.map.lock();
2926            map.nodes[0].flags |= FLAG_NOFAILOVER;
2927        }));
2928        // A master that was serving nothing has nothing to take over.
2929        assert!(refused(T0, |server| {
2930            let mut map = server.cluster.map.lock();
2931            for slot in 0..=5460 {
2932                map.owner[slot] = Some(2);
2933            }
2934        }));
2935        // Data too old to be worth promoting. The link went down long enough
2936        // ago that this node has missed more than a failover is allowed to
2937        // lose, on top of the silence that made the master dead.
2938        let stale = T0 + NODE_TIMEOUT_MS + STALE_DATA_MS + 1;
2939        assert!(refused(stale, |server| {
2940            server.pretend_following("10.0.0.1", 7001, false);
2941            server.pretend_master_down_at(T0);
2942        }));
2943        // A second less and it stands, which is what makes the line above a
2944        // test of the bound rather than of the setup.
2945        assert!(!refused(stale - 1000, |server| {
2946            server.pretend_following("10.0.0.1", 7001, false);
2947            server.pretend_master_down_at(T0);
2948        }));
2949    }
2950
2951    /// The same table the other way round, with this node as the master and
2952    /// node 1 as the replica that is about to ask it to stand down.
2953    fn standing() -> Arc<Server> {
2954        let server = shard();
2955        {
2956            let mut map = server.cluster.map.lock();
2957            map.nodes[0].flags &= !FLAG_SLAVE;
2958            map.nodes[0].flags |= FLAG_MASTER;
2959            map.nodes[0].master = None;
2960            map.nodes[1].flags &= !FLAG_MASTER;
2961            map.nodes[1].flags |= FLAG_SLAVE;
2962            map.nodes[1].master = Some(0);
2963            for slot in 0..=5460 {
2964                map.owner[slot] = Some(0);
2965            }
2966        }
2967        server.recount_coverage();
2968        server
2969    }
2970
2971    /// The master's half of a manual failover, which is to stop taking writes
2972    /// and say where it stopped.
2973    #[test]
2974    fn a_master_asked_to_stand_down_stops_writing_and_says_where() {
2975        let server = standing();
2976        let mut todo = Todo::default();
2977        {
2978            let map = server.cluster.map.lock();
2979            stand_down(&server, &map, 2, T0, &mut todo);
2980        }
2981        assert!(todo.reply.is_empty(), "only a replica of this node may ask");
2982        assert_eq!(server.pause_ends(), 0);
2983
2984        {
2985            let map = server.cluster.map.lock();
2986            stand_down(&server, &map, 1, T0, &mut todo);
2987        }
2988        let reply = todo
2989            .reply
2990            .first()
2991            .expect("answered at once, not by the cron");
2992        assert_eq!(be16(reply, O_TYPE), T_PING);
2993        assert!(
2994            reply[O_MFLAGS] & MF_PAUSED != 0,
2995            "and the answer says the writes have stopped"
2996        );
2997        assert_eq!(be64(reply, O_OFFSET), server.repl_offset());
2998        // Held for twice as long as the failover has to finish in, so that the
2999        // master is still holding them at the moment the replica gives up.
3000        assert_eq!(
3001            server.pause_ends(),
3002            T0 + MANUAL_TIMEOUT_MS * MANUAL_PAUSE_MULT
3003        );
3004        assert_eq!(
3005            server.paused(T0),
3006            Some(false),
3007            "the writes and not the reads"
3008        );
3009
3010        // And lets go on its own when nothing came of it, which is the one
3011        // outcome worth going out of the way to avoid getting wrong.
3012        manual_cron(&server, T0 + MANUAL_TIMEOUT_MS + 1);
3013        assert_eq!(server.cluster.manual.end.load(Relaxed), 0);
3014        assert_eq!(server.pause_ends(), 0);
3015    }
3016
3017    /// The replica's half, which is to wait for the offsets to meet and then go
3018    /// straight to the front of the queue.
3019    #[test]
3020    fn a_manual_failover_waits_for_the_offsets_to_meet() {
3021        let server = shard();
3022        let step = |now: u64| {
3023            let mut map = server.cluster.map.lock();
3024            decide(&server, &mut map, now)
3025        };
3026        let manual = &server.cluster.manual;
3027        manual.end.store(T0 + MANUAL_TIMEOUT_MS, Relaxed);
3028
3029        // The master is up and has not said anything yet, so there is nothing
3030        // to stand for.
3031        assert!(matches!(step(T0), Step::Idle));
3032        manual_cron(&server, T0);
3033        assert!(!manual.can_start.load(Relaxed), "no offset from the master");
3034        manual.offset.store(server.repl_offset() + 1, Relaxed);
3035        manual_cron(&server, T0);
3036        assert!(!manual.can_start.load(Relaxed), "still behind the master");
3037        assert!(matches!(step(T0), Step::Idle));
3038
3039        // Caught up with everything the master wrote before it stopped, which
3040        // is the moment this is safe and the only one.
3041        manual.offset.store(server.repl_offset(), Relaxed);
3042        manual_cron(&server, T0);
3043        assert!(manual.can_start.load(Relaxed));
3044
3045        // No fixed delay, no random delay and no rank, because there is nothing
3046        // to let propagate and nobody else is standing.
3047        assert!(matches!(step(T0), Step::Announce));
3048        assert_eq!(server.cluster.vote.at.load(Relaxed), T0);
3049        assert_eq!(server.cluster.vote.rank.load(Relaxed), 0);
3050        let Step::Ask(packet) = step(T0) else {
3051            panic!("nothing to wait for on this path");
3052        };
3053        assert!(
3054            packet[O_MFLAGS] & MF_FORCEACK != 0,
3055            "the master is up and is in on it, so say so"
3056        );
3057
3058        server.cluster.vote.count.store(2, Relaxed);
3059        assert!(matches!(step(T0), Step::Won));
3060        let map = server.cluster.map.lock();
3061        assert!(map.nodes[0].is_master());
3062        assert_eq!(map.owner[5460], Some(0));
3063        assert_eq!(
3064            map.owner[5461],
3065            Some(2),
3066            "and nothing that was not its master's"
3067        );
3068    }
3069
3070    /// `CLUSTER FAILOVER` refuses where the reference refuses, and each of its
3071    /// three forms does a different amount of asking.
3072    #[test]
3073    fn cluster_failover_refuses_where_the_reference_refuses() {
3074        let ends = |e: Error, want: &str| {
3075            let text = e.to_string();
3076            assert!(text.ends_with(want), "wanted {want}, got {text}");
3077        };
3078        let server = standing();
3079        ends(
3080            manual_failover(&server, false, false).unwrap_err(),
3081            "You should send CLUSTER FAILOVER to a replica",
3082        );
3083        {
3084            let mut map = server.cluster.map.lock();
3085            map.nodes[0].flags &= !FLAG_MASTER;
3086            map.nodes[0].flags |= FLAG_SLAVE;
3087            map.nodes[0].master = None;
3088        }
3089        ends(
3090            manual_failover(&server, false, false).unwrap_err(),
3091            "I'm a replica but my master is unknown to me",
3092        );
3093
3094        // A master with no link to it cannot be asked to hold its clients
3095        // still, so the plain form says which form to use instead.
3096        let server = shard();
3097        server.cluster.map.lock().nodes[1].linked = false;
3098        ends(
3099            manual_failover(&server, false, false).unwrap_err(),
3100            "Master is down or failed, please use CLUSTER FAILOVER FORCE",
3101        );
3102        server.cluster.map.lock().nodes[1].linked = true;
3103        server.cluster.map.lock().nodes[1].flags |= FLAG_FAIL;
3104        ends(
3105            manual_failover(&server, false, false).unwrap_err(),
3106            "Master is down or failed, please use CLUSTER FAILOVER FORCE",
3107        );
3108        server.cluster.map.lock().nodes[1].flags &= !FLAG_FAIL;
3109        manual_failover(&server, false, false).unwrap();
3110        assert_ne!(server.cluster.manual.end.load(Relaxed), 0);
3111        assert!(
3112            !server.cluster.manual.can_start.load(Relaxed),
3113            "the plain form waits for the master to answer"
3114        );
3115        assert!(server.cluster.map.lock().nodes[0].flags & FLAG_SLAVE != 0);
3116
3117        // FORCE does not ask the master, but it does still stand for election.
3118        let server = shard();
3119        manual_failover(&server, true, false).unwrap();
3120        assert!(server.cluster.manual.can_start.load(Relaxed));
3121        assert!(server.cluster.map.lock().nodes[0].flags & FLAG_SLAVE != 0);
3122
3123        // TAKEOVER does not ask anybody at all.
3124        let server = shard();
3125        manual_failover(&server, true, true).unwrap();
3126        assert_eq!(
3127            server.cluster.manual.end.load(Relaxed),
3128            0,
3129            "nothing left to wait for"
3130        );
3131        let map = server.cluster.map.lock();
3132        assert!(map.nodes[0].is_master());
3133        assert_eq!(map.nodes[0].epoch, 1, "under an epoch it made up");
3134        assert_eq!(map.owner[0], Some(0));
3135        assert_eq!(map.owner[5460], Some(0));
3136        assert_eq!(map.owner[5461], Some(2));
3137    }
3138
3139    #[test]
3140    fn a_node_id_has_to_be_forty_hex_characters() {
3141        let mut p = vec![0u8; NAME_LEN * 3];
3142        assert_eq!(node_id(&p, 0), None, "all zeros is the reference's no node");
3143        p[0..NAME_LEN].copy_from_slice(&[b'a'; NAME_LEN]);
3144        assert_eq!(node_id(&p, 0).as_deref(), Some("a".repeat(40).as_str()));
3145        p[5] = b'z';
3146        assert_eq!(node_id(&p, 0), None);
3147        assert_eq!(node_id(&p, NAME_LEN * 3), None, "off the end is not an id");
3148    }
3149}