pub struct PeerBoard { /* private fields */ }Expand description
The peers of one server process.
Implementations§
Source§impl PeerBoard
impl PeerBoard
Sourcepub fn attach(&self, transport: Transport) -> PeerId
pub fn attach(&self, transport: Transport) -> PeerId
A session attached; it has no name until PeerBoard::identify.
use majordomus_cli::peers::{PeerBoard, Transport};
let board = PeerBoard::new();
let a = board.attach(Transport::Stdio);
let b = board.attach(Transport::Http);
assert_eq!((a.as_str(), b.as_str()), ("p1", "p2"));
board.detach(&a);
assert_eq!(board.list().len(), 1);Sourcepub fn identify(&self, id: &PeerId, client: ClientInfo)
pub fn identify(&self, id: &PeerId, client: ClientInfo)
The client behind a peer, from its initialize.
Sourcepub fn announce(
&self,
id: &PeerId,
intent: &str,
scope: Vec<String>,
) -> Option<Announced>
pub fn announce( &self, id: &PeerId, intent: &str, scope: Vec<String>, ) -> Option<Announced>
Record a peer’s unnamed claim, and answer with who else is on that ground.
This is the whole of what a session announcing about itself needs, and it is what
announcing has always meant: the peer holds one claim and each announcement replaces
it. A connection doing several things at once wants PeerBoard::announce_claim.
None when the id is not attached. The overlap is computed here, under the same
lock as the write, so that two peers announcing at once cannot both be told they
are alone.
use majordomus_cli::peers::{PeerBoard, Transport};
let board = PeerBoard::new();
let a = board.attach(Transport::Stdio);
let b = board.attach(Transport::Http);
board.announce(&a, "the ordering rule", vec!["apps/majordomus-cli/src".into()]);
let second = board
.announce(&b, "the release model", vec!["apps/majordomus-cli/src/release".into()])
.unwrap();
assert_eq!(second.overlaps.len(), 1, "a claim inside another claim is an overlap");
assert_eq!(second.overlaps[0].intent, "the ordering rule");
// announcing again, narrower: the peer is told what it stopped claiming
let again = board.announce(&b, "the release model", vec![]).unwrap();
assert_eq!(again.released, vec!["apps/majordomus-cli/src/release".to_string()]);Sourcepub fn announce_claim(
&self,
id: &PeerId,
claim: Option<&str>,
intent: &str,
scope: Vec<String>,
) -> Option<Announced>
pub fn announce_claim( &self, id: &PeerId, claim: Option<&str>, intent: &str, scope: Vec<String>, ) -> Option<Announced>
The same, naming which of the peer’s claims this is.
None is PeerBoard::announce: the peer’s one unnamed claim. Every other value
is a claim of its own, held beside the rest until it is announced again under the
same name.
use majordomus_cli::peers::{PeerBoard, Transport};
let board = PeerBoard::new();
let fleet = board.attach(Transport::Http);
board.announce(&fleet, "the whole mandate", vec!["docs".into()]);
let named = board
.announce_claim(&fleet, Some("worker-a"), "the guard", vec![".claude".into()])
.unwrap();
assert_eq!(named.peer.claims.len(), 2, "the unnamed claim still stands");
assert_eq!(named.peer.claims[1].name.as_deref(), Some("worker-a"));Sourcepub fn overlaps(&self) -> Vec<Overlap>
pub fn overlaps(&self) -> Vec<Overlap>
Every pair of claims that meet, each pair once, in peer order.
A peer holding several claims is asked about each of them, so two connections that collide on two different claims are reported twice, with the intent of each. That is the answer a reader wants: it is not “these two sessions overlap” but “these two pieces of work overlap”, and the intent says which.
Sourcepub fn detach(&self, id: &PeerId)
pub fn detach(&self, id: &PeerId)
The session ended.
A peer that announced something is kept and marked departed rather than removed:
what a session said it was working on is a fact about the repository, and it does
not stop being true because a socket closed. A peer that never announced leaves
nothing behind. The oldest departed slot past RETAINED is dropped.
use majordomus_cli::peers::{PeerBoard, Transport};
let board = PeerBoard::new();
let quiet = board.attach(Transport::Http);
let spoken = board.attach(Transport::Http);
board.announce(&spoken, "the ordering rule", vec!["apps".into()]);
board.detach(&quiet);
board.detach(&spoken);
assert_eq!(board.len(), 0, "neither is attached any more");
let listed = board.list();
assert_eq!(listed.len(), 1, "the one that said something is still on the board");
assert!(!listed[0].attached);
assert_eq!(listed[0].announcement.as_ref().unwrap().intent, "the ordering rule");