Skip to main content

admission_conflicts

Function admission_conflicts 

Source
pub fn admission_conflicts<'a>(
    state: &'a CooperationState,
    session: &str,
    scope: &[String],
    mode: ClaimMode,
) -> Vec<&'a ClaimView>
Expand description

The live exclusive claims of other sessions a new exclusive claim of session over scope would meet: empty means admissible. An advisory claim is always admissible.

This is the difference between refusing a claim and reporting a conflict after the fact. Admission is checked against the folded state before anything is written, so a claim that could have been refused is refused; what is left — genuinely concurrent claims from two sides of a partition — is what the fold ranks afterwards, and both runtimes name the same winner.

use std::sync::Arc;
use majordomus_cli::mesh::identity::NodeIdentity;
use majordomus_cli::mesh::journal::{ClaimMode, EventBody, Journal, StreamLiveness};
use majordomus_cli::mesh::state::{admission_conflicts, fold};

let j = Journal::open(Arc::new(NodeIdentity::ephemeral().unwrap()), "0000000000000001",
    "repo".into(), None).unwrap();
j.append_own(EventBody::ClaimAcquired { claim: "c1".into(), session: "s1".into(),
    scope: vec!["apps".into()], intent: None, mode: ClaimMode::Exclusive, issue: None })
    .unwrap();
let state = fold(&j.events(), &|_| StreamLiveness::Own);
let held = &state.claims[0];

// another session cannot take a scope inside one already held exclusively
let met = admission_conflicts(&state, "s2", &["apps/majordomus-cli".into()],
    ClaimMode::Exclusive);
assert_eq!(met.len(), 1);
assert_eq!(met[0].key, held.key, "the refusal names what it met");

// the holder is not in its own way, and an advisory claim is never refused
assert!(admission_conflicts(&state, &held.session, &["apps".into()], ClaimMode::Exclusive)
    .is_empty());
assert!(admission_conflicts(&state, "s2", &["apps".into()], ClaimMode::Advisory).is_empty());