use arc_swap::ArcSwapOption;
use std::collections::{BTreeMap, BTreeSet};
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use super::org::OrgId;
use super::org_grant::CapabilityAuthorityId;
use super::org_routing::{ApplyOutcome, ApplyRequest, DirtyApply, RegistryWork};
use super::org_scoped_ingest::CapabilityAudienceScope;
use super::org_scoped_store::{DirtyCapabilities, PrivateCapabilityProvider};
use crate::adapter::net::identity::EntityId;
pub(crate) const MAX_HANDLES_PER_FAMILY: usize = 64;
pub(crate) const MAX_NODE_SLOTS: usize = 256;
const APPLY_QUANTUM: usize = 64;
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
struct FamilyId(u64);
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct PrivateAudienceScope(CapabilityAudienceScope);
impl PrivateAudienceScope {
#[allow(dead_code)] pub(crate) fn new(scope: CapabilityAudienceScope) -> Option<Self> {
match scope {
CapabilityAudienceScope::Public => None,
private => Some(Self(private)),
}
}
pub(crate) fn scope(&self) -> &CapabilityAudienceScope {
&self.0
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct SlotKey {
pub scope: PrivateAudienceScope,
pub capability: CapabilityAuthorityId,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum DemandRefused {
#[allow(dead_code)]
FamilyAtCapacity,
#[allow(dead_code)]
NodeAtCapacity,
IdSpaceExhausted,
}
#[derive(Clone, Debug)]
pub(crate) struct SlotBaseFacts {
#[allow(dead_code)] pub providers: SourceFacts,
pub epoch: SourceEpoch,
pub authority: ScopedDiscoveryAuthorityStamp,
pub actor_incarnation: u64,
pub slot_incarnation: u64,
pub grant_fence: GrantArtifactFence,
pub earliest_expiry: u64,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub(crate) struct SourceEpoch {
pub generation: u64,
pub authority: u64,
pub floor_generation: u64,
pub poisoned: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum ScopedDiscoveryAuthorityStamp {
Owner,
Grant {
grant_id: [u8; 32],
install_seq: u64,
grant_signature: [u8; 64],
audience_handle: [u8; 32],
},
}
#[derive(Clone, Debug)]
pub(crate) struct ScopedSourceFacts {
pub facts: SourceFacts,
pub authority: ScopedDiscoveryAuthorityStamp,
pub authority_deadline: u64,
pub grant_fence: GrantArtifactFence,
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub(crate) struct SourceToken(Vec<u64>);
impl SourceToken {
pub(crate) fn new(words: Vec<u64>) -> Self {
Self(words)
}
}
#[derive(Clone, Debug)]
pub(crate) enum SourceFacts {
Served(Arc<[PrivateCapabilityProvider]>),
Unserved,
}
pub(crate) trait SourceSnapshot {
fn token(&self) -> SourceToken;
fn providers(&self, key: &SlotKey) -> ScopedSourceFacts;
}
pub(crate) trait SourceCommitPin {
fn epoch(&self) -> SourceEpoch;
fn settle_if_current(&self, settle: &mut dyn FnMut() -> ApplyOutcome) -> Option<ApplyOutcome>;
}
pub(crate) trait SlotSource: Send + Sync + 'static {
fn snapshot(&self, keys: &[SlotKey]) -> Box<dyn SourceSnapshot>;
fn pin_if_current(
&self,
keys: &[SlotKey],
expected: &SourceToken,
) -> Option<Box<dyn SourceCommitPin + '_>>;
fn liveness(&self) -> SourceLiveness {
SourceLiveness::Live
}
fn session_view(&self) -> SessionObservation {
SessionObservation::cold()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum SourceLiveness {
Live,
Fenced,
Terminal,
}
impl SourceLiveness {
fn may_self_wake(self) -> bool {
matches!(self, Self::Live)
}
fn may_requeue(self) -> bool {
!matches!(self, Self::Terminal)
}
}
#[derive(Debug)]
pub(crate) struct SessionCurrentness {
generation: AtomicU64,
}
impl Default for SessionCurrentness {
fn default() -> Self {
Self {
generation: AtomicU64::new(0),
}
}
}
impl SessionCurrentness {
pub(crate) fn new() -> Arc<Self> {
Arc::new(Self::default())
}
pub(crate) fn generation(&self) -> Option<u64> {
match self.generation.load(Ordering::Acquire) {
u64::MAX => None,
live => Some(live),
}
}
pub(crate) fn reserve(&self) -> Option<u64> {
let next = self.generation.load(Ordering::Acquire).checked_add(1)?;
(next != u64::MAX).then_some(next)
}
pub(crate) fn commit(&self, generation: u64) {
self.generation.store(generation, Ordering::Release);
}
pub(crate) fn exhaust(&self) {
self.generation.store(u64::MAX, Ordering::Release);
}
#[cfg(test)]
pub(crate) fn set_for_test(&self, generation: u64) {
self.generation.store(generation, Ordering::Release);
}
}
pub(crate) trait SessionEligibility: Send + Sync {
fn eligibility(&self, provider: &EntityId) -> DirectEligibility;
}
struct ColdSessionProjection;
impl SessionEligibility for ColdSessionProjection {
fn eligibility(&self, _provider: &EntityId) -> DirectEligibility {
DirectEligibility::Cold
}
}
pub(crate) struct SessionObservation {
generation: Option<u64>,
rows: Arc<dyn SessionEligibility>,
currentness: Arc<SessionCurrentness>,
}
impl std::fmt::Debug for SessionObservation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SessionObservation")
.field("generation", &self.generation)
.finish_non_exhaustive()
}
}
impl SessionObservation {
pub(crate) fn new(
generation: Option<u64>,
rows: Arc<dyn SessionEligibility>,
currentness: Arc<SessionCurrentness>,
) -> Self {
Self {
generation,
rows,
currentness,
}
}
fn cold() -> Self {
Self {
generation: Some(0),
rows: Arc::new(ColdSessionProjection),
currentness: SessionCurrentness::new(),
}
}
fn eligibility(&self, provider: &EntityId) -> DirectEligibility {
self.rows.eligibility(provider)
}
fn still_current(&self) -> bool {
match (self.generation, self.currentness.generation()) {
(Some(observed), Some(live)) => observed == live,
_ => false,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum ProviderProvenance {
OwnerPlane,
GrantPlane {
grant_id: [u8; 32],
audience_handle: [u8; 32],
},
}
impl ProviderProvenance {
fn of(authority: &ScopedDiscoveryAuthorityStamp) -> Self {
match authority {
ScopedDiscoveryAuthorityStamp::Owner => Self::OwnerPlane,
ScopedDiscoveryAuthorityStamp::Grant {
grant_id,
audience_handle,
..
} => Self::GrantPlane {
grant_id: *grant_id,
audience_handle: *audience_handle,
},
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum DirectEligibility {
Direct { node_id: u64, session_id: u64 },
Relayed { node_id: u64, session_id: u64 },
Cold,
}
impl DirectEligibility {
#[allow(dead_code)] pub(crate) fn is_direct(&self) -> bool {
matches!(self, Self::Direct { .. })
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct UnsensedRouteRow {
pub provider: EntityId,
pub owner_org: OrgId,
pub generation: u64,
pub expires_at: u64,
pub direct: DirectEligibility,
}
#[derive(Debug)]
pub(crate) struct ScopedUnsensedRoutePool {
derived_from: Arc<SlotBaseFacts>,
key: SlotKey,
authority: ScopedDiscoveryAuthorityStamp,
epoch: SourceEpoch,
provenance: ProviderProvenance,
providers: Arc<[UnsensedRouteRow]>,
session_generation: u64,
earliest_deadline: u64,
}
#[allow(dead_code)] impl ScopedUnsensedRoutePool {
pub(crate) fn derived_from(&self) -> &Arc<SlotBaseFacts> {
&self.derived_from
}
pub(crate) fn derives_from(&self, facts: &Arc<SlotBaseFacts>) -> bool {
Arc::ptr_eq(&self.derived_from, facts)
}
pub(crate) fn key(&self) -> &SlotKey {
&self.key
}
pub(crate) fn authority(&self) -> &ScopedDiscoveryAuthorityStamp {
&self.authority
}
pub(crate) fn epoch(&self) -> SourceEpoch {
self.epoch
}
pub(crate) fn provenance(&self) -> ProviderProvenance {
self.provenance
}
pub(crate) fn providers(&self) -> &[UnsensedRouteRow] {
&self.providers
}
pub(crate) fn session_generation(&self) -> u64 {
self.session_generation
}
pub(crate) fn earliest_deadline(&self) -> u64 {
self.earliest_deadline
}
#[cfg(test)]
pub(crate) fn for_test(derived_from: Arc<SlotBaseFacts>) -> Self {
Self::for_test_at_session(derived_from, 0)
}
#[cfg(test)]
pub(crate) fn for_test_at_session(
derived_from: Arc<SlotBaseFacts>,
session_generation: u64,
) -> Self {
Self {
key: SlotKey {
scope: PrivateAudienceScope(CapabilityAudienceScope::Owner {
org_id: OrgId::from_bytes([0; 32]),
audience_handle: [0; 32],
}),
capability: CapabilityAuthorityId::for_tag("test:pool"),
},
authority: derived_from.authority,
epoch: derived_from.epoch,
provenance: ProviderProvenance::of(&derived_from.authority),
providers: Arc::from(Vec::new()),
session_generation,
earliest_deadline: derived_from.earliest_expiry,
derived_from,
}
}
}
#[derive(Debug)]
struct PreparedRoutePool {
key: SlotKey,
authority: ScopedDiscoveryAuthorityStamp,
provenance: ProviderProvenance,
providers: Arc<[UnsensedRouteRow]>,
session_generation: u64,
}
impl PreparedRoutePool {
fn seal(self, derived_from: Arc<SlotBaseFacts>) -> Arc<ScopedUnsensedRoutePool> {
Arc::new(ScopedUnsensedRoutePool {
key: self.key,
authority: self.authority,
epoch: derived_from.epoch,
provenance: self.provenance,
providers: self.providers,
session_generation: self.session_generation,
earliest_deadline: derived_from.earliest_expiry,
derived_from,
})
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum PublicationGap {
PoolCleared,
FactsInstalled,
}
#[derive(Default)]
struct PublicationObserver {
#[cfg(test)]
#[allow(clippy::type_complexity)]
hook: parking_lot::Mutex<Option<Arc<dyn Fn(PublicationGap) + Send + Sync>>>,
}
impl PublicationObserver {
#[inline]
fn observe(&self, _gap: PublicationGap) {
#[cfg(test)]
{
let hook = self.hook.lock().clone();
if let Some(hook) = hook {
hook(_gap);
}
}
}
}
#[derive(Clone, Debug)]
struct SlotCells {
facts: Arc<ArcSwapOption<SlotBaseFacts>>,
unsensed: Arc<ArcSwapOption<ScopedUnsensedRoutePool>>,
}
impl SlotCells {
fn empty() -> Self {
Self {
facts: Arc::new(ArcSwapOption::empty()),
unsensed: Arc::new(ArcSwapOption::empty()),
}
}
fn take_facts(&self) -> Option<Arc<SlotBaseFacts>> {
self.unsensed.store(None);
self.facts.swap(None)
}
fn take_pool(&self) -> Option<Arc<ScopedUnsensedRoutePool>> {
self.unsensed.swap(None)
}
#[cfg(test)]
fn install_facts(&self, facts: Arc<SlotBaseFacts>) {
self.install_facts_and_pool(facts, None, &PublicationObserver::default());
}
fn install_facts_and_pool(
&self,
facts: Arc<SlotBaseFacts>,
pool: Option<Arc<ScopedUnsensedRoutePool>>,
observer: &PublicationObserver,
) {
debug_assert!(
pool.as_ref()
.is_none_or(|pool| Arc::ptr_eq(&pool.derived_from, &facts)),
"a published pool names the facts it is published beside"
);
self.unsensed.store(None);
observer.observe(PublicationGap::PoolCleared);
self.facts.store(Some(facts));
observer.observe(PublicationGap::FactsInstalled);
if pool.is_some() {
self.unsensed.store(pool);
}
}
}
#[derive(Debug)]
struct Slot {
incarnation: u64,
#[allow(dead_code)]
refs: usize,
cells: SlotCells,
}
impl Slot {
fn new(incarnation: u64) -> Self {
Self {
incarnation,
refs: 1,
cells: SlotCells::empty(),
}
}
}
#[derive(Default)]
struct RegistryInner {
slots: BTreeMap<SlotKey, Slot>,
slots_by_capability: BTreeMap<CapabilityAuthorityId, BTreeSet<SlotKey>>,
#[allow(dead_code)]
families: BTreeMap<FamilyId, BTreeMap<SlotKey, usize>>,
pending: BTreeSet<SlotKey>,
next_id: u64,
live_actor: Option<u64>,
recapture_open: bool,
select_cursor: Option<SlotKey>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum ReleaseOutcome {
Released,
Retire,
NotHeld,
}
impl RegistryInner {
#[allow(dead_code)]
fn family_handles(&self, family: FamilyId) -> usize {
self.families
.get(&family)
.map_or(0, |keys| keys.values().sum())
}
fn release_one(&mut self, family: FamilyId, key: &SlotKey) -> ReleaseOutcome {
let held = self
.families
.get(&family)
.and_then(|keys| keys.get(key))
.copied()
.unwrap_or(0);
if held == 0 {
return ReleaseOutcome::NotHeld;
}
if let Some(keys) = self.families.get_mut(&family) {
if let Some(count) = keys.get_mut(key) {
*count -= 1;
if *count == 0 {
keys.remove(key);
}
}
if keys.is_empty() {
self.families.remove(&family);
}
}
match self.slots.get_mut(key) {
Some(slot) => {
slot.refs -= 1;
if slot.refs == 0 {
ReleaseOutcome::Retire
} else {
ReleaseOutcome::Released
}
}
None => ReleaseOutcome::Released,
}
}
fn allocate_id(&mut self) -> Option<u64> {
let next = self.next_id.checked_add(1)?;
self.next_id = next;
Some(next)
}
fn invalidate(&mut self, key: &SlotKey) -> bool {
self.slots
.get_mut(key)
.is_some_and(|slot| slot.cells.take_facts().is_some())
}
fn invalidate_and_queue_all(&mut self) -> u64 {
let keys: Vec<SlotKey> = self.slots.keys().cloned().collect();
let mut invalidated = 0;
for key in keys {
if self.invalidate(&key) {
invalidated += 1;
}
self.pending.insert(key);
}
invalidated
}
fn incoherent_with(&self, incarnation: u64, epoch: SourceEpoch) -> Vec<SlotKey> {
self.slots
.iter()
.filter(|(_, slot)| {
!slot.cells.facts.load().as_ref().is_some_and(|facts| {
facts.actor_incarnation == incarnation
&& facts.slot_incarnation == slot.incarnation
&& facts.epoch == epoch
})
})
.map(|(key, _)| key.clone())
.collect()
}
}
#[derive(Default)]
pub(crate) struct RegistryMetrics {
refused_family_at_capacity: AtomicU64,
refused_node_at_capacity: AtomicU64,
refused_id_space_exhausted: AtomicU64,
slots_retired: AtomicU64,
installs: AtomicU64,
discarded_obsolete: AtomicU64,
facts_invalidated: AtomicU64,
stale_actor_rejections: AtomicU64,
recaptures_restarted: AtomicU64,
settlements_refused: AtomicU64,
pools_published: AtomicU64,
pools_invalidated: AtomicU64,
pools_refused_stale_session: AtomicU64,
}
impl RegistryMetrics {
pub(crate) fn refused_family_at_capacity(&self) -> u64 {
self.refused_family_at_capacity.load(Ordering::Acquire)
}
pub(crate) fn refused_node_at_capacity(&self) -> u64 {
self.refused_node_at_capacity.load(Ordering::Acquire)
}
pub(crate) fn refused_id_space_exhausted(&self) -> u64 {
self.refused_id_space_exhausted.load(Ordering::Acquire)
}
pub(crate) fn slots_retired(&self) -> u64 {
self.slots_retired.load(Ordering::Acquire)
}
pub(crate) fn installs(&self) -> u64 {
self.installs.load(Ordering::Acquire)
}
pub(crate) fn discarded_obsolete(&self) -> u64 {
self.discarded_obsolete.load(Ordering::Acquire)
}
pub(crate) fn facts_invalidated(&self) -> u64 {
self.facts_invalidated.load(Ordering::Acquire)
}
pub(crate) fn stale_actor_rejections(&self) -> u64 {
self.stale_actor_rejections.load(Ordering::Acquire)
}
pub(crate) fn recaptures_restarted(&self) -> u64 {
self.recaptures_restarted.load(Ordering::Acquire)
}
pub(crate) fn settlements_refused(&self) -> u64 {
self.settlements_refused.load(Ordering::Acquire)
}
#[cfg(test)]
pub(crate) fn pools_published(&self) -> u64 {
self.pools_published.load(Ordering::Acquire)
}
#[cfg(test)]
pub(crate) fn pools_invalidated(&self) -> u64 {
self.pools_invalidated.load(Ordering::Acquire)
}
#[cfg(test)]
pub(crate) fn pools_refused_stale_session(&self) -> u64 {
self.pools_refused_stale_session.load(Ordering::Acquire)
}
}
pub(crate) struct NodeOrgRoutingRegistry {
inner: parking_lot::Mutex<RegistryInner>,
source: Arc<dyn SlotSource>,
work: Arc<RegistryWork>,
metrics: Arc<RegistryMetrics>,
node_capacity_generation: AtomicU64,
ref_release_generation: AtomicU64,
publication_observer: PublicationObserver,
}
#[allow(dead_code)]
#[derive(Clone)]
pub(crate) struct RoutingFamily {
registry: Arc<NodeOrgRoutingRegistry>,
id: FamilyId,
}
#[allow(dead_code)]
impl RoutingFamily {
pub(crate) fn demand(&self, key: SlotKey) -> Result<DemandHandle, DemandRefused> {
self.registry.demand(self.id, key)
}
pub(crate) fn demand_set(&self, keys: Vec<SlotKey>) -> Result<DemandSet, DemandRefused> {
self.registry.demand_set(self.id, keys)
}
pub(crate) fn handles(&self) -> usize {
self.registry.inner.lock().family_handles(self.id)
}
pub(crate) fn node_capacity_generation(&self) -> u64 {
self.registry.node_capacity_generation()
}
pub(crate) fn ref_release_generation(&self) -> u64 {
self.registry.ref_release_generation()
}
}
#[allow(dead_code)]
pub(crate) struct DemandHandle {
registry: Arc<NodeOrgRoutingRegistry>,
family: FamilyId,
key: SlotKey,
cells: SlotCells,
}
impl DemandHandle {
#[allow(dead_code)]
pub(crate) fn base_facts_unvalidated(&self) -> Option<Arc<SlotBaseFacts>> {
self.cells.facts.load_full()
}
#[allow(dead_code)] pub(crate) fn unsensed_pool_unvalidated(&self) -> Option<Arc<ScopedUnsensedRoutePool>> {
self.cells.unsensed.load_full()
}
}
impl Drop for DemandHandle {
fn drop(&mut self) {
self.registry.release(self.family, &self.key);
}
}
#[allow(dead_code)] pub(crate) struct DemandSet {
registry: Arc<NodeOrgRoutingRegistry>,
family: FamilyId,
keys: Vec<SlotKey>,
cells: Vec<SlotCells>,
held: parking_lot::Mutex<Vec<SlotKey>>,
}
#[allow(dead_code)] impl DemandSet {
pub(crate) fn keys(&self) -> &[SlotKey] {
&self.keys
}
pub(crate) fn len(&self) -> usize {
self.keys.len()
}
pub(crate) fn is_empty(&self) -> bool {
self.keys.is_empty()
}
pub(crate) fn base_facts_unvalidated(&self, index: usize) -> Option<Arc<SlotBaseFacts>> {
self.cells.get(index)?.facts.load_full()
}
#[allow(dead_code)] pub(crate) fn unsensed_pool_unvalidated(
&self,
index: usize,
) -> Option<Arc<ScopedUnsensedRoutePool>> {
self.cells.get(index)?.unsensed.load_full()
}
#[cfg(test)]
pub(crate) fn held_for_test(&self) -> Vec<SlotKey> {
self.held.lock().clone()
}
pub(crate) fn replace(&self, new_keys: Vec<SlotKey>) -> Result<DemandSet, ReplaceRefused> {
self.registry
.clone()
.replace_demand_set(self.family, self, new_keys)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[allow(dead_code)] pub(crate) enum ReplaceRefused {
Demand(DemandRefused),
Superseded,
}
impl Drop for DemandSet {
fn drop(&mut self) {
let owed = std::mem::take(&mut *self.held.lock());
if !owed.is_empty() {
self.registry.release_keys(self.family, &owed);
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum GrantArtifactFence {
Publication(u64),
TerminalAbsence,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum GrantMovementFence {
Publication(u64),
Terminal,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) struct GrantScopeMovement {
pub grant_id: [u8; 32],
pub audience_handle: [u8; 32],
pub fence: GrantMovementFence,
}
impl GrantScopeMovement {
fn covers(&self, key: &SlotKey) -> bool {
matches!(
key.scope.scope(),
CapabilityAudienceScope::Grant {
grant_id,
audience_handle,
} if grant_id == &self.grant_id && audience_handle == &self.audience_handle
)
}
}
impl NodeOrgRoutingRegistry {
pub(crate) fn new(
source: Arc<dyn SlotSource>,
work: Arc<RegistryWork>,
metrics: Arc<RegistryMetrics>,
) -> Arc<Self> {
Arc::new(Self {
inner: parking_lot::Mutex::new(RegistryInner::default()),
source,
work,
metrics,
node_capacity_generation: AtomicU64::new(0),
ref_release_generation: AtomicU64::new(0),
publication_observer: PublicationObserver::default(),
})
}
#[cfg(test)]
pub(crate) fn observe_publication_for_test(
&self,
hook: Arc<dyn Fn(PublicationGap) + Send + Sync>,
) {
*self.publication_observer.hook.lock() = Some(hook);
}
pub(crate) fn node_capacity_generation(&self) -> u64 {
self.node_capacity_generation.load(Ordering::Acquire)
}
pub(crate) fn ref_release_generation(&self) -> u64 {
self.ref_release_generation.load(Ordering::Acquire)
}
pub(crate) fn new_family(self: &Arc<Self>) -> Result<RoutingFamily, DemandRefused> {
let id = {
let mut inner = self.inner.lock();
inner.allocate_id()
};
match id {
Some(id) => Ok(RoutingFamily {
registry: self.clone(),
id: FamilyId(id),
}),
None => {
self.metrics
.refused_id_space_exhausted
.fetch_add(1, Ordering::AcqRel);
Err(DemandRefused::IdSpaceExhausted)
}
}
}
#[allow(dead_code)]
fn demand(
self: &Arc<Self>,
family: FamilyId,
key: SlotKey,
) -> Result<DemandHandle, DemandRefused> {
let mut queued = false;
let cells = {
let mut inner = self.inner.lock();
if inner.family_handles(family) >= MAX_HANDLES_PER_FAMILY {
self.metrics
.refused_family_at_capacity
.fetch_add(1, Ordering::AcqRel);
return Err(DemandRefused::FamilyAtCapacity);
}
let new_slot = !inner.slots.contains_key(&key);
if new_slot && inner.slots.len() >= MAX_NODE_SLOTS {
self.metrics
.refused_node_at_capacity
.fetch_add(1, Ordering::AcqRel);
return Err(DemandRefused::NodeAtCapacity);
}
let cells = if new_slot {
let Some(incarnation) = inner.allocate_id() else {
self.metrics
.refused_id_space_exhausted
.fetch_add(1, Ordering::AcqRel);
return Err(DemandRefused::IdSpaceExhausted);
};
let slot = Slot::new(incarnation);
let cells = slot.cells.clone();
inner.slots.insert(key.clone(), slot);
inner
.slots_by_capability
.entry(key.capability)
.or_default()
.insert(key.clone());
inner.pending.insert(key.clone());
queued = true;
cells
} else {
let Some(slot) = inner.slots.get_mut(&key) else {
return Err(DemandRefused::NodeAtCapacity);
};
slot.refs += 1;
slot.cells.clone()
};
*inner
.families
.entry(family)
.or_default()
.entry(key.clone())
.or_insert(0) += 1;
cells
};
if queued {
self.work.mark();
}
Ok(DemandHandle {
registry: self.clone(),
family,
key,
cells,
})
}
#[allow(dead_code)] fn demand_set(
self: &Arc<Self>,
family: FamilyId,
keys: Vec<SlotKey>,
) -> Result<DemandSet, DemandRefused> {
let mut keys = keys;
keys.sort();
keys.dedup();
let mut queued = false;
let cells = {
let mut inner = self.inner.lock();
if inner.family_handles(family) + keys.len() > MAX_HANDLES_PER_FAMILY {
self.metrics
.refused_family_at_capacity
.fetch_add(1, Ordering::AcqRel);
return Err(DemandRefused::FamilyAtCapacity);
}
let new_slots = keys
.iter()
.filter(|key| !inner.slots.contains_key(key))
.count();
if inner.slots.len() + new_slots > MAX_NODE_SLOTS {
self.metrics
.refused_node_at_capacity
.fetch_add(1, Ordering::AcqRel);
return Err(DemandRefused::NodeAtCapacity);
}
let Some(reserved_through) = inner.next_id.checked_add(new_slots as u64) else {
self.metrics
.refused_id_space_exhausted
.fetch_add(1, Ordering::AcqRel);
return Err(DemandRefused::IdSpaceExhausted);
};
let mut next_incarnation = inner.next_id;
inner.next_id = reserved_through;
let mut cells = Vec::with_capacity(keys.len());
for key in &keys {
let slot_cells = match inner.slots.get_mut(key) {
Some(slot) => {
slot.refs += 1;
slot.cells.clone()
}
None => {
next_incarnation += 1;
let slot = Slot::new(next_incarnation);
let slot_cells = slot.cells.clone();
inner.slots.insert(key.clone(), slot);
inner
.slots_by_capability
.entry(key.capability)
.or_default()
.insert(key.clone());
inner.pending.insert(key.clone());
queued = true;
slot_cells
}
};
*inner
.families
.entry(family)
.or_default()
.entry(key.clone())
.or_insert(0) += 1;
cells.push(slot_cells);
}
debug_assert_eq!(next_incarnation, reserved_through, "reservation is exact");
cells
};
if queued {
self.work.mark();
}
Ok(DemandSet {
registry: self.clone(),
family,
keys: keys.clone(),
cells,
held: parking_lot::Mutex::new(keys),
})
}
#[allow(dead_code)]
fn release(&self, family: FamilyId, key: &SlotKey) {
let mut inner = self.inner.lock();
match inner.release_one(family, key) {
ReleaseOutcome::Retire => {
self.retire_committed(&mut inner, key);
self.note_ref_released();
}
ReleaseOutcome::Released => self.note_ref_released(),
ReleaseOutcome::NotHeld => {}
}
}
fn release_keys(&self, family: FamilyId, keys: &[SlotKey]) {
let mut inner = self.inner.lock();
let mut released = false;
for key in keys {
match inner.release_one(family, key) {
ReleaseOutcome::Retire => {
self.retire_committed(&mut inner, key);
released = true;
}
ReleaseOutcome::Released => released = true,
ReleaseOutcome::NotHeld => {}
}
}
if released {
self.note_ref_released();
}
}
fn note_ref_released(&self) {
self.ref_release_generation.fetch_add(1, Ordering::AcqRel);
}
fn retire_committed(&self, inner: &mut RegistryInner, key: &SlotKey) {
if let Some(slot) = inner.slots.get(key) {
slot.cells.take_facts();
}
inner.slots.remove(key);
inner.pending.remove(key);
if let Some(bucket) = inner.slots_by_capability.get_mut(&key.capability) {
bucket.remove(key);
if bucket.is_empty() {
inner.slots_by_capability.remove(&key.capability);
}
}
self.metrics.slots_retired.fetch_add(1, Ordering::AcqRel);
self.node_capacity_generation.fetch_add(1, Ordering::AcqRel);
}
fn replace_demand_set(
self: &Arc<Self>,
family: FamilyId,
old: &DemandSet,
new_keys: Vec<SlotKey>,
) -> Result<DemandSet, ReplaceRefused> {
let mut new_keys = new_keys;
new_keys.sort();
new_keys.dedup();
let mut held = old.held.lock();
if *held != old.keys {
return Err(ReplaceRefused::Superseded);
}
let mut queued = false;
let mut released = false;
let cells = {
let mut inner = self.inner.lock();
let old_only: Vec<SlotKey> = held
.iter()
.filter(|key| new_keys.binary_search(key).is_err())
.cloned()
.collect();
let new_only: Vec<SlotKey> = new_keys
.iter()
.filter(|key| held.binary_search(key).is_err())
.cloned()
.collect();
let projected =
inner.family_handles(family).saturating_sub(old_only.len()) + new_only.len();
if projected > MAX_HANDLES_PER_FAMILY {
self.metrics
.refused_family_at_capacity
.fetch_add(1, Ordering::AcqRel);
return Err(ReplaceRefused::Demand(DemandRefused::FamilyAtCapacity));
}
let credited = old_only
.iter()
.filter(|key| inner.slots.get(key).is_some_and(|slot| slot.refs == 1))
.count();
let created = new_only
.iter()
.filter(|key| !inner.slots.contains_key(key))
.count();
let projected_slots = inner.slots.len().saturating_sub(credited) + created;
if projected_slots > MAX_NODE_SLOTS {
self.metrics
.refused_node_at_capacity
.fetch_add(1, Ordering::AcqRel);
return Err(ReplaceRefused::Demand(DemandRefused::NodeAtCapacity));
}
let Some(reserved_through) = inner.next_id.checked_add(created as u64) else {
self.metrics
.refused_id_space_exhausted
.fetch_add(1, Ordering::AcqRel);
return Err(ReplaceRefused::Demand(DemandRefused::IdSpaceExhausted));
};
let mut next_incarnation = inner.next_id;
inner.next_id = reserved_through;
for key in &old_only {
match inner.release_one(family, key) {
ReleaseOutcome::Retire => {
self.retire_committed(&mut inner, key);
released = true;
}
ReleaseOutcome::Released => released = true,
ReleaseOutcome::NotHeld => {}
}
}
for key in &new_only {
match inner.slots.get_mut(key) {
Some(slot) => slot.refs += 1,
None => {
next_incarnation += 1;
inner.slots.insert(key.clone(), Slot::new(next_incarnation));
inner
.slots_by_capability
.entry(key.capability)
.or_default()
.insert(key.clone());
inner.pending.insert(key.clone());
queued = true;
}
}
*inner
.families
.entry(family)
.or_default()
.entry(key.clone())
.or_insert(0) += 1;
}
debug_assert_eq!(next_incarnation, reserved_through, "reservation is exact");
new_keys
.iter()
.map(|key| {
#[allow(clippy::expect_used)]
let slot = inner
.slots
.get(key)
.expect("every key of the new set is retained above");
slot.cells.clone()
})
.collect::<Vec<_>>()
};
held.clear();
drop(held);
if released {
self.note_ref_released();
}
if queued {
self.work.mark();
}
Ok(DemandSet {
registry: self.clone(),
family,
keys: new_keys.clone(),
cells,
held: parking_lot::Mutex::new(new_keys),
})
}
pub(crate) fn base_facts_unvalidated(&self, key: &SlotKey) -> Option<Arc<SlotBaseFacts>> {
self.inner.lock().slots.get(key)?.cells.facts.load_full()
}
pub(crate) fn invalidate_authority_older_than(&self, live: u64) {
let owed = {
let mut inner = self.inner.lock();
let stale: Vec<SlotKey> = inner
.slots
.iter()
.filter(|(_, slot)| {
slot.cells
.facts
.load()
.as_ref()
.is_some_and(|facts| facts.epoch.authority < live)
})
.map(|(key, _)| key.clone())
.collect();
let mut invalidated = 0;
for key in stale {
if inner.invalidate(&key) {
invalidated += 1;
}
inner.pending.insert(key);
}
self.metrics
.facts_invalidated
.fetch_add(invalidated, Ordering::AcqRel);
!inner.pending.is_empty()
};
if owed {
self.work.mark();
}
}
pub(crate) fn invalidate_if_stale(&self, key: &SlotKey, observed: &Arc<SlotBaseFacts>) {
let owed = {
let mut inner = self.inner.lock();
let Some(slot) = inner.slots.get_mut(key) else {
return;
};
let still_observed = slot
.cells
.facts
.load()
.as_ref()
.is_some_and(|live| Arc::ptr_eq(live, observed));
if !still_observed {
return;
}
slot.cells.take_facts();
self.metrics
.facts_invalidated
.fetch_add(1, Ordering::AcqRel);
inner.pending.insert(key.clone());
true
};
if owed {
self.work.mark();
}
}
pub(crate) fn invalidate_session_older_than(&self, live: u64) -> u64 {
let (retired, owed) = {
let mut inner = self.inner.lock();
let superseded: Vec<SlotKey> = inner
.slots
.iter()
.filter(|(_, slot)| {
slot.cells
.unsensed
.load()
.as_ref()
.is_some_and(|pool| pool.session_generation < live)
})
.map(|(key, _)| key.clone())
.collect();
let mut retired = 0u64;
for key in superseded {
if let Some(slot) = inner.slots.get(&key) {
if slot.cells.take_pool().is_some() {
retired += 1;
}
}
inner.pending.insert(key);
}
self.metrics
.pools_invalidated
.fetch_add(retired, Ordering::AcqRel);
(retired, !inner.pending.is_empty())
};
if owed {
self.work.mark();
}
retired
}
pub(crate) fn invalidate_grant_scope(&self, movement: &GrantScopeMovement) -> u64 {
let (retired, owed) = {
let mut inner = self.inner.lock();
let affected: Vec<SlotKey> = inner
.slots
.keys()
.filter(|key| movement.covers(key))
.cloned()
.collect();
let mut retired = 0u64;
for key in affected {
let Some(cells) = inner.slots.get(&key).map(|slot| slot.cells.clone()) else {
continue;
};
let superseded = match cells.facts.load().as_ref() {
None => true,
Some(facts) => match (facts.grant_fence, movement.fence) {
(
GrantArtifactFence::TerminalAbsence,
GrantMovementFence::Publication(_),
) => false,
(GrantArtifactFence::TerminalAbsence, GrantMovementFence::Terminal) => {
false
}
(GrantArtifactFence::Publication(_), GrantMovementFence::Terminal) => true,
(
GrantArtifactFence::Publication(artifact),
GrantMovementFence::Publication(publication),
) => artifact < publication,
},
};
if !superseded {
continue;
}
if cells.take_facts().is_some() {
retired += 1;
}
inner.pending.insert(key);
}
self.metrics
.facts_invalidated
.fetch_add(retired, Ordering::AcqRel);
(retired, !inner.pending.is_empty())
};
if owed {
self.work.mark();
}
retired
}
pub(crate) fn retire_terminal(&self) {
let mut inner = self.inner.lock();
let mut invalidated = 0u64;
for slot in inner.slots.values_mut() {
if slot.cells.take_facts().is_some() {
invalidated += 1;
}
}
inner.pending.clear();
inner.recapture_open = false;
self.metrics
.facts_invalidated
.fetch_add(invalidated, Ordering::AcqRel);
}
pub(crate) fn next_artifact_deadline(&self) -> Option<u64> {
self.inner
.lock()
.slots
.values()
.filter_map(|slot| slot.cells.facts.load().as_ref().map(|f| f.earliest_expiry))
.filter(|deadline| *deadline != u64::MAX)
.min()
}
pub(crate) fn retire_expired(&self, now_secs: u64) -> u64 {
let mut inner = self.inner.lock();
let expired: Vec<SlotKey> = inner
.slots
.iter()
.filter(|(_, slot)| {
slot.cells
.facts
.load()
.as_ref()
.is_some_and(|f| now_secs >= f.earliest_expiry)
})
.map(|(key, _)| key.clone())
.collect();
let mut retired = 0u64;
for key in expired {
if let Some(slot) = inner.slots.get_mut(&key) {
if slot.cells.take_facts().is_some() {
retired += 1;
}
}
inner.pending.insert(key);
}
self.metrics
.facts_invalidated
.fetch_add(retired, Ordering::AcqRel);
retired
}
#[cfg(test)]
pub(crate) fn requeue_for_test(&self, key: &SlotKey) {
self.inner.lock().pending.insert(key.clone());
}
#[cfg(test)]
pub(crate) fn take_pool_for_test(&self, key: &SlotKey) {
let inner = self.inner.lock();
if let Some(slot) = inner.slots.get(key) {
slot.cells.take_pool();
}
}
#[cfg(test)]
pub(crate) fn invalidate_for_test(&self, key: &SlotKey) {
let mut inner = self.inner.lock();
inner.invalidate(key);
inner.pending.insert(key.clone());
}
#[cfg(test)]
pub(crate) fn release_one_for_test(&self, family: &RoutingFamily, key: &SlotKey) {
let mut inner = self.inner.lock();
match inner.release_one(family.id, key) {
ReleaseOutcome::Retire => {
self.retire_committed(&mut inner, key);
drop(inner);
self.note_ref_released();
}
ReleaseOutcome::Released => {
drop(inner);
self.note_ref_released();
}
ReleaseOutcome::NotHeld => {}
}
}
#[cfg(test)]
pub(crate) fn install_facts_for_test(&self, key: SlotKey, facts: Arc<SlotBaseFacts>) {
let mut inner = self.inner.lock();
let slot = inner.slots.entry(key).or_insert_with(|| Slot::new(1));
slot.cells.install_facts(facts);
}
#[cfg(test)]
pub(crate) fn install_unsensed_pool_for_test(
&self,
key: &SlotKey,
pool: Arc<ScopedUnsensedRoutePool>,
) {
let inner = self.inner.lock();
if let Some(slot) = inner.slots.get(key) {
slot.cells.unsensed.store(Some(pool));
}
}
pub(crate) fn unsensed_pool_unvalidated(
&self,
key: &SlotKey,
) -> Option<Arc<ScopedUnsensedRoutePool>> {
self.inner.lock().slots.get(key)?.cells.unsensed.load_full()
}
pub(crate) fn retained_slots(&self) -> usize {
self.inner.lock().slots.len()
}
pub(crate) fn pending_slots(&self) -> usize {
self.inner.lock().pending.len()
}
#[cfg(test)]
pub(crate) fn allocated_ids_for_test(&self) -> u64 {
self.inner.lock().next_id
}
#[cfg(test)]
pub(crate) fn exhaust_ids_for_test(&self) {
self.inner.lock().next_id = u64::MAX;
}
}
impl NodeOrgRoutingRegistry {
fn mark_if_movement(&self) {
if self.source.liveness().may_self_wake() {
self.work.mark();
}
}
}
impl DirtyApply for NodeOrgRoutingRegistry {
fn activate_incarnation(&self, incarnation: u64) {
let owed = {
let mut inner = self.inner.lock();
inner.live_actor = Some(incarnation);
inner.recapture_open = false;
let invalidated = inner.invalidate_and_queue_all();
self.metrics
.facts_invalidated
.fetch_add(invalidated, Ordering::AcqRel);
!inner.pending.is_empty()
};
if owed {
self.work.mark();
}
}
fn deactivate_incarnation(&self, incarnation: u64) {
let mut inner = self.inner.lock();
if inner.live_actor == Some(incarnation) {
inner.live_actor = None;
}
}
fn next_deadline(&self) -> Option<u64> {
self.next_artifact_deadline()
}
fn retire_expired(&self, now_secs: u64) -> u64 {
NodeOrgRoutingRegistry::retire_expired(self, now_secs)
}
fn apply(&self, incarnation: u64, request: ApplyRequest) -> ApplyOutcome {
let selected: Vec<(SlotKey, u64)> = {
let mut inner = self.inner.lock();
if inner.live_actor != Some(incarnation) {
self.metrics
.stale_actor_rejections
.fetch_add(1, Ordering::AcqRel);
drop(inner);
self.work.mark();
return ApplyOutcome::Superseded;
}
let mut invalidated = 0u64;
let mut named: BTreeSet<SlotKey> = BTreeSet::new();
match &request.batch.dirty {
DirtyCapabilities::RebuildAll => {
if !inner.recapture_open {
inner.recapture_open = true;
invalidated += inner.invalidate_and_queue_all();
}
named = inner.pending.clone();
}
DirtyCapabilities::Caps(caps) => {
let affected: Vec<SlotKey> = caps
.iter()
.filter_map(|capability| inner.slots_by_capability.get(capability))
.flat_map(|bucket| bucket.iter().cloned())
.collect();
for key in affected {
if inner.invalidate(&key) {
invalidated += 1;
}
inner.pending.insert(key.clone());
named.insert(key);
}
}
DirtyCapabilities::Clean => {}
}
if request.registry_work {
named.extend(inner.pending.iter().cloned());
}
self.metrics
.facts_invalidated
.fetch_add(invalidated, Ordering::AcqRel);
let rotated: Vec<SlotKey> = match &inner.select_cursor {
Some(cursor) => named
.range((
std::ops::Bound::Excluded(cursor.clone()),
std::ops::Bound::Unbounded,
))
.chain(named.range((
std::ops::Bound::Unbounded,
std::ops::Bound::Included(cursor.clone()),
)))
.take(APPLY_QUANTUM)
.cloned()
.collect(),
None => named.iter().take(APPLY_QUANTUM).cloned().collect(),
};
inner.select_cursor = rotated.last().cloned().or(inner.select_cursor.take());
let mut selected = Vec::with_capacity(rotated.len());
for key in rotated {
inner.pending.remove(&key);
if let Some(slot) = inner.slots.get(&key) {
selected.push((key, slot.incarnation));
}
}
selected
};
if selected.is_empty() {
let probe = self.source.snapshot(&[]);
let token = probe.token();
drop(probe);
let Some(commit) = self.source.pin_if_current(&[], &token) else {
self.mark_if_movement();
return ApplyOutcome::Superseded;
};
let epoch = commit.epoch();
let mut inner = self.inner.lock();
if inner.live_actor != Some(incarnation) {
self.metrics
.stale_actor_rejections
.fetch_add(1, Ordering::AcqRel);
let owed = !inner.pending.is_empty();
drop(inner);
if owed {
self.work.mark();
}
return ApplyOutcome::Superseded;
}
let Some(outcome) = commit
.settle_if_current(&mut || settle(&mut inner, incarnation, epoch, &self.metrics))
else {
drop(inner);
self.metrics
.settlements_refused
.fetch_add(1, Ordering::AcqRel);
self.mark_if_movement();
return ApplyOutcome::Superseded;
};
let owed = !inner.pending.is_empty();
drop(inner);
if owed {
self.work.mark();
}
return outcome;
}
let keys: Vec<SlotKey> = selected.iter().map(|(key, _)| key.clone()).collect();
let snapshot = self.source.snapshot(&keys);
let snapshot_token = snapshot.token();
let sessions = self.source.session_view();
let built: Vec<BuiltSlot> = selected
.iter()
.map(|(key, slot_incarnation)| {
let facts = snapshot.providers(key);
let prepared = prepare_route_pool(key, &facts, &sessions);
BuiltSlot {
key: key.clone(),
slot_incarnation: *slot_incarnation,
facts,
prepared,
}
})
.collect();
drop(snapshot);
let Some(commit) = self.source.pin_if_current(&keys, &snapshot_token) else {
let liveness = self.source.liveness();
let mut inner = self.inner.lock();
if liveness.may_requeue() {
for built in &built {
if inner
.slots
.get(&built.key)
.is_some_and(|slot| slot.incarnation == built.slot_incarnation)
{
inner.pending.insert(built.key.clone());
}
}
}
self.metrics
.discarded_obsolete
.fetch_add(built.len() as u64, Ordering::AcqRel);
drop(inner);
if liveness.may_self_wake() {
self.work.mark();
}
return ApplyOutcome::Superseded;
};
let epoch = commit.epoch();
let mut slot_moved = false;
let outcome = {
let mut inner = self.inner.lock();
if inner.live_actor != Some(incarnation) {
for built in &built {
if inner
.slots
.get(&built.key)
.is_some_and(|slot| slot.incarnation == built.slot_incarnation)
{
inner.pending.insert(built.key.clone());
}
}
self.metrics
.stale_actor_rejections
.fetch_add(1, Ordering::AcqRel);
self.metrics
.discarded_obsolete
.fetch_add(built.len() as u64, Ordering::AcqRel);
drop(inner);
self.work.mark();
return ApplyOutcome::Superseded;
}
let session_current = sessions.still_current();
let RegistryInner { slots, pending, .. } = &mut *inner;
for BuiltSlot {
key,
slot_incarnation,
facts,
prepared,
} in built
{
let Some(slot) = slots.get_mut(&key) else {
self.metrics
.discarded_obsolete
.fetch_add(1, Ordering::AcqRel);
continue;
};
if slot.incarnation != slot_incarnation {
self.metrics
.discarded_obsolete
.fetch_add(1, Ordering::AcqRel);
pending.insert(key);
slot_moved = true;
continue;
}
let ScopedSourceFacts {
facts,
authority,
authority_deadline,
grant_fence,
} = facts;
let row_expiry = match &facts {
SourceFacts::Served(providers) => providers
.iter()
.map(|p| p.expires_at)
.min()
.unwrap_or(u64::MAX),
SourceFacts::Unserved => u64::MAX,
};
let earliest_expiry = row_expiry.min(authority_deadline);
let facts = Arc::new(SlotBaseFacts {
providers: facts,
epoch,
authority,
grant_fence,
actor_incarnation: incarnation,
slot_incarnation,
earliest_expiry,
});
let pool = match prepared {
Some(prepared) if session_current => Some(prepared.seal(facts.clone())),
Some(_) => {
self.metrics
.pools_refused_stale_session
.fetch_add(1, Ordering::AcqRel);
pending.insert(key.clone());
None
}
None => None,
};
let published = pool.is_some();
slot.cells
.install_facts_and_pool(facts, pool, &self.publication_observer);
self.metrics.installs.fetch_add(1, Ordering::AcqRel);
if published {
self.metrics.pools_published.fetch_add(1, Ordering::AcqRel);
}
}
let settled = commit
.settle_if_current(&mut || settle(&mut inner, incarnation, epoch, &self.metrics));
let Some(settled) = settled else {
let liveness = self.source.liveness();
if liveness.may_requeue() {
for (key, slot_incarnation) in &selected {
if inner
.slots
.get(key)
.is_some_and(|slot| slot.incarnation == *slot_incarnation)
{
inner.pending.insert(key.clone());
}
}
}
self.metrics
.settlements_refused
.fetch_add(1, Ordering::AcqRel);
drop(inner);
if liveness.may_self_wake() {
self.work.mark();
}
return ApplyOutcome::Superseded;
};
let owed = !inner.pending.is_empty();
drop(inner);
if owed {
self.work.mark();
}
if slot_moved {
ApplyOutcome::Superseded
} else {
settled
}
};
drop(commit);
outcome
}
}
struct BuiltSlot {
key: SlotKey,
slot_incarnation: u64,
facts: ScopedSourceFacts,
prepared: Option<PreparedRoutePool>,
}
fn prepare_route_pool(
key: &SlotKey,
facts: &ScopedSourceFacts,
sessions: &SessionObservation,
) -> Option<PreparedRoutePool> {
let SourceFacts::Served(providers) = &facts.facts else {
return None;
};
let session_generation = sessions.generation?;
let rows: Vec<UnsensedRouteRow> = providers
.iter()
.map(|provider| UnsensedRouteRow {
provider: provider.provider.clone(),
owner_org: provider.owner_org,
generation: provider.generation,
expires_at: provider.expires_at,
direct: sessions.eligibility(&provider.provider),
})
.collect();
Some(PreparedRoutePool {
key: key.clone(),
authority: facts.authority,
provenance: ProviderProvenance::of(&facts.authority),
providers: rows.into(),
session_generation,
})
}
fn settle(
inner: &mut RegistryInner,
incarnation: u64,
epoch: SourceEpoch,
metrics: &RegistryMetrics,
) -> ApplyOutcome {
if inner.recapture_open {
let mut displaced = 0;
for key in inner.incoherent_with(incarnation, epoch) {
if inner.invalidate(&key) {
displaced += 1;
}
inner.pending.insert(key);
}
if displaced > 0 {
metrics
.facts_invalidated
.fetch_add(displaced, Ordering::AcqRel);
metrics.recaptures_restarted.fetch_add(1, Ordering::AcqRel);
}
}
if inner.pending.is_empty() {
inner.recapture_open = false;
ApplyOutcome::Current {
source_generation: epoch.generation,
}
} else {
ApplyOutcome::Progress {
source_generation: epoch.generation,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::adapter::net::behavior::org::OrgId;
use std::sync::atomic::AtomicBool;
fn scope(seed: u8) -> PrivateAudienceScope {
PrivateAudienceScope::new(CapabilityAudienceScope::Owner {
org_id: OrgId::from_bytes([seed; 32]),
audience_handle: [seed; 32],
})
.expect("owner scopes are private")
}
fn key(seed: u8, tag: &str) -> SlotKey {
SlotKey {
scope: scope(seed),
capability: CapabilityAuthorityId::for_tag(tag),
}
}
type Hook = Box<dyn Fn() + Send + Sync>;
type SharedHook = Arc<dyn Fn() + Send + Sync>;
fn entity(seed: u8) -> EntityId {
EntityId::from_bytes([seed; 32])
}
fn provider_row(seed: u8, generation: u64, expires_at: u64) -> PrivateCapabilityProvider {
PrivateCapabilityProvider {
provider: entity(seed),
owner_org: OrgId::from_bytes([seed.wrapping_add(0x40); 32]),
expires_at,
generation,
}
}
#[derive(Default)]
struct TestProjection {
generation: u64,
rows: BTreeMap<EntityId, DirectEligibility>,
registry: Option<Arc<NodeOrgRoutingRegistry>>,
}
impl SessionEligibility for TestProjection {
fn eligibility(&self, provider: &EntityId) -> DirectEligibility {
if let Some(registry) = self.registry.as_ref() {
assert!(
registry.inner.try_lock().is_some(),
"no registry lock may be held while the pool is built"
);
}
self.rows
.get(provider)
.copied()
.unwrap_or(DirectEligibility::Cold)
}
}
struct TestSessions {
currentness: Arc<SessionCurrentness>,
published: parking_lot::Mutex<Arc<TestProjection>>,
registry: parking_lot::Mutex<Option<Arc<NodeOrgRoutingRegistry>>>,
observations: AtomicU64,
}
impl TestSessions {
fn new() -> Self {
Self {
currentness: SessionCurrentness::new(),
published: parking_lot::Mutex::new(Arc::new(TestProjection::default())),
registry: parking_lot::Mutex::new(None),
observations: AtomicU64::new(0),
}
}
fn publish(&self, rows: BTreeMap<EntityId, DirectEligibility>) -> u64 {
let generation = self.currentness.reserve().expect("generation space");
let registry = self.registry.lock().clone();
*self.published.lock() = Arc::new(TestProjection {
generation,
rows,
registry,
});
self.currentness.commit(generation);
generation
}
fn observe(&self) -> SessionObservation {
self.observations.fetch_add(1, Ordering::AcqRel);
let published = self.published.lock().clone();
let generation = self.currentness.generation().map(|_| published.generation);
SessionObservation::new(generation, published, self.currentness.clone())
}
}
fn direct(node_id: u64) -> DirectEligibility {
DirectEligibility::Direct {
node_id,
session_id: node_id ^ 0xfeed,
}
}
struct SourceState {
gate: parking_lot::Mutex<u64>,
authority_moved: AtomicBool,
during_build: parking_lot::Mutex<Option<Hook>>,
on_snapshot: parking_lot::Mutex<Option<Hook>>,
on_commit_release: parking_lot::Mutex<Option<SharedHook>>,
queried: parking_lot::Mutex<Vec<SlotKey>>,
snapshots: AtomicU64,
registry: parking_lot::Mutex<Option<Arc<NodeOrgRoutingRegistry>>>,
rows: parking_lot::Mutex<Vec<PrivateCapabilityProvider>>,
authority_deadline: AtomicU64,
unserved: AtomicBool,
sessions: TestSessions,
}
impl SourceState {
fn new() -> Arc<Self> {
Arc::new(Self {
gate: parking_lot::Mutex::new(1),
authority_moved: AtomicBool::new(false),
during_build: parking_lot::Mutex::new(None),
on_snapshot: parking_lot::Mutex::new(None),
on_commit_release: parking_lot::Mutex::new(None),
queried: parking_lot::Mutex::new(Vec::new()),
snapshots: AtomicU64::new(0),
registry: parking_lot::Mutex::new(None),
rows: parking_lot::Mutex::new(Vec::new()),
authority_deadline: AtomicU64::new(u64::MAX),
unserved: AtomicBool::new(false),
sessions: TestSessions::new(),
})
}
fn queries(&self) -> Vec<SlotKey> {
self.queried.lock().clone()
}
fn reset(&self) {
self.queried.lock().clear();
}
fn generation(&self) -> u64 {
*self.gate.lock()
}
fn advance(&self) {
*self.gate.lock() += 1;
}
fn assert_no_registry_lock(&self, context: &str) {
if let Some(registry) = self.registry.lock().clone() {
assert!(registry.inner.try_lock().is_some(), "{context}");
}
}
}
struct TestSource(Arc<SourceState>);
struct TestSnapshot {
state: Arc<SourceState>,
generation: u64,
_captured: Vec<SlotKey>,
}
impl SourceSnapshot for TestSnapshot {
fn token(&self) -> SourceToken {
SourceToken::new(vec![self.generation])
}
fn providers(&self, key: &SlotKey) -> ScopedSourceFacts {
self.state.queried.lock().push(key.clone());
self.state
.assert_no_registry_lock("no registry lock may be held across reconstruction");
assert!(
self.state.gate.try_lock().is_some(),
"no source/publication lock may be held across decode, sort or projection"
);
let hook = self.state.during_build.lock().take();
if let Some(hook) = hook {
hook();
}
let unserved = self.state.unserved.load(Ordering::Acquire);
let facts = if unserved {
SourceFacts::Unserved
} else {
SourceFacts::Served(self.state.rows.lock().clone().into())
};
ScopedSourceFacts {
facts,
authority: ScopedDiscoveryAuthorityStamp::Owner,
grant_fence: GrantArtifactFence::Publication(0),
authority_deadline: if unserved {
u64::MAX
} else {
self.state.authority_deadline.load(Ordering::Acquire)
},
}
}
}
struct TestCommitPin<'a> {
state: Arc<SourceState>,
generation: parking_lot::MutexGuard<'a, u64>,
}
impl SourceCommitPin for TestCommitPin<'_> {
fn settle_if_current(
&self,
settle: &mut dyn FnMut() -> ApplyOutcome,
) -> Option<ApplyOutcome> {
(!self.state.authority_moved.load(Ordering::Acquire)).then(settle)
}
fn epoch(&self) -> SourceEpoch {
SourceEpoch {
generation: *self.generation,
authority: 0,
floor_generation: 0,
poisoned: false,
}
}
}
impl Drop for TestCommitPin<'_> {
fn drop(&mut self) {
let hook = self.state.on_commit_release.lock().clone();
if let Some(hook) = hook {
hook();
}
}
}
impl SlotSource for TestSource {
fn snapshot(&self, keys: &[SlotKey]) -> Box<dyn SourceSnapshot> {
self.0
.assert_no_registry_lock("no registry lock may be held across the source snapshot");
let generation = *self.0.gate.lock();
self.0.snapshots.fetch_add(1, Ordering::AcqRel);
let hook = self.0.on_snapshot.lock().take();
if let Some(hook) = hook {
hook();
}
Box::new(TestSnapshot {
state: self.0.clone(),
generation,
_captured: keys.to_vec(),
})
}
fn session_view(&self) -> SessionObservation {
self.0
.assert_no_registry_lock("no registry lock may be held across the session capture");
self.0.sessions.observe()
}
fn pin_if_current(
&self,
_keys: &[SlotKey],
expected: &SourceToken,
) -> Option<Box<dyn SourceCommitPin + '_>> {
self.0.assert_no_registry_lock(
"the commit pin must be acquired BEFORE the registry lock",
);
let generation = self.0.gate.lock();
if SourceToken::new(vec![*generation]) != *expected {
return None;
}
Some(Box::new(TestCommitPin {
state: self.0.clone(),
generation,
}))
}
}
struct Fixture {
registry: Arc<NodeOrgRoutingRegistry>,
source: Arc<SourceState>,
metrics: Arc<RegistryMetrics>,
}
impl Fixture {
fn family(&self) -> RoutingFamily {
self.registry.new_family().expect("family")
}
}
fn fixture() -> Fixture {
let source = SourceState::new();
let metrics: Arc<RegistryMetrics> = Arc::default();
let registry = NodeOrgRoutingRegistry::new(
Arc::new(TestSource(source.clone())),
Arc::default(),
metrics.clone(),
);
*source.registry.lock() = Some(registry.clone());
*source.sessions.registry.lock() = Some(registry.clone());
registry.activate_incarnation(1);
Fixture {
registry,
source,
metrics,
}
}
fn facts() -> Arc<SlotBaseFacts> {
Arc::new(SlotBaseFacts {
providers: SourceFacts::Unserved,
epoch: SourceEpoch::default(),
authority: ScopedDiscoveryAuthorityStamp::Owner,
actor_incarnation: 1,
slot_incarnation: 1,
grant_fence: GrantArtifactFence::Publication(0),
earliest_expiry: u64::MAX,
})
}
fn request(registry_work: bool, dirty: DirtyCapabilities) -> ApplyRequest {
ApplyRequest {
batch: crate::adapter::net::behavior::org_scoped_store::PrivateDiscoveryChangeBatch {
generation: 1,
dirty,
},
registry_work,
}
}
fn caps(tags: &[&str]) -> DirtyCapabilities {
DirtyCapabilities::Caps(
tags.iter()
.map(|t| CapabilityAuthorityId::for_tag(t))
.collect(),
)
}
#[test]
fn the_public_scope_cannot_form_a_slot_key() {
assert!(
PrivateAudienceScope::new(CapabilityAudienceScope::Public).is_none(),
"this is the PRIVATE routing consumer"
);
assert!(PrivateAudienceScope::new(CapabilityAudienceScope::Owner {
org_id: OrgId::from_bytes([7; 32]),
audience_handle: [7; 32],
})
.is_some());
}
#[test]
fn a_clone_family_shares_one_identity_and_one_budget() {
let f = fixture();
let family = f.family();
let clone = family.clone();
let independent = f.family();
let _a = family.demand(key(1, "nrpc:a")).expect("a");
let _b = clone.demand(key(1, "nrpc:b")).expect("b");
assert_eq!(family.handles(), 2, "the clone spends the SAME budget");
assert_eq!(clone.handles(), 2);
assert_eq!(independent.handles(), 0, "a distinct family is unaffected");
let mut held = Vec::new();
for index in 0..(MAX_HANDLES_PER_FAMILY - 2) {
held.push(
clone
.demand(key(1, &format!("nrpc:s{index}")))
.expect("within the shared bound"),
);
}
assert_eq!(
family.demand(key(1, "nrpc:over")).err(),
Some(DemandRefused::FamilyAtCapacity),
"the original clone is bounded by what its clone spent"
);
assert!(
independent.demand(key(1, "nrpc:own")).is_ok(),
"an independent family still has its own budget"
);
}
#[test]
fn first_demand_after_drained_deltas_still_gets_a_full_recapture() {
let f = fixture();
f.registry
.apply(1, request(false, DirtyCapabilities::RebuildAll));
f.source.reset();
let family = f.family();
let _held = family.demand(key(1, "nrpc:a")).expect("demand");
assert_eq!(f.registry.pending_slots(), 1);
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert_eq!(f.source.queries(), vec![key(1, "nrpc:a")]);
assert!(matches!(outcome, ApplyOutcome::Current { .. }));
let facts = f
.registry
.base_facts_unvalidated(&key(1, "nrpc:a"))
.expect("built");
assert_eq!(facts.slot_incarnation, 2, "family 1, then this slot");
assert_eq!(facts.actor_incarnation, 1);
assert_eq!(f.registry.pending_slots(), 0);
}
#[test]
fn two_families_share_one_slot_and_one_reconstruction() {
let f = fixture();
let a = f.family().demand(key(1, "nrpc:a")).expect("a");
let b = f.family().demand(key(1, "nrpc:a")).expect("b");
assert_eq!(f.registry.retained_slots(), 1, "one shared node slot");
f.source.reset();
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert_eq!(
f.source.queries(),
vec![key(1, "nrpc:a")],
"reconstructed once per SLOT, not once per family"
);
drop((a, b));
}
#[test]
fn a_different_audience_scope_is_a_different_slot() {
let f = fixture();
let family = f.family();
let _a = family.demand(key(1, "nrpc:a")).expect("a");
let _b = family.demand(key(2, "nrpc:a")).expect("b");
assert_eq!(
f.registry.retained_slots(),
2,
"same capability, different scope => distinct slots"
);
f.source.reset();
f.registry.apply(1, request(false, caps(&["nrpc:a"])));
let mut queried = f.source.queries();
queried.sort();
let mut expected = vec![key(1, "nrpc:a"), key(2, "nrpc:a")];
expected.sort();
assert_eq!(
queried, expected,
"the capability bucket holds both scoped slots, each rebuilt separately"
);
}
#[test]
fn the_sixty_fifth_family_handle_is_refused_without_corrupting_the_first_64() {
let f = fixture();
let family = f.family();
let mut held = Vec::new();
for index in 0..MAX_HANDLES_PER_FAMILY {
held.push(
family
.demand(key(1, &format!("nrpc:f{index}")))
.expect("within the bound"),
);
}
assert_eq!(
family.demand(key(1, "nrpc:over")).err(),
Some(DemandRefused::FamilyAtCapacity)
);
assert_eq!(
family.demand(key(1, "nrpc:f0")).err(),
Some(DemandRefused::FamilyAtCapacity),
"duplicate demand cannot bypass the handle bound"
);
assert_eq!(f.metrics.refused_family_at_capacity(), 2);
assert_eq!(
f.registry.retained_slots(),
MAX_HANDLES_PER_FAMILY,
"the first 64 are intact and no slot was created for the refusals"
);
assert_eq!(held.len(), MAX_HANDLES_PER_FAMILY);
}
#[test]
fn the_two_hundred_fifty_seventh_slot_is_deterministically_unretained() {
let f = fixture();
let mut held = Vec::new();
let mut family = f.family();
for index in 0..MAX_NODE_SLOTS {
if index > 0 && index % MAX_HANDLES_PER_FAMILY == 0 {
family = f.family();
}
held.push(
family
.demand(key(1, &format!("nrpc:n{index}")))
.expect("within the node bound"),
);
}
assert_eq!(f.registry.retained_slots(), MAX_NODE_SLOTS);
let beyond = key(1, "nrpc:beyond");
assert_eq!(
f.family().demand(beyond.clone()).err(),
Some(DemandRefused::NodeAtCapacity)
);
assert_eq!(f.metrics.refused_node_at_capacity(), 1);
assert_eq!(
f.registry.retained_slots(),
MAX_NODE_SLOTS,
"no live slot was evicted to make room"
);
assert!(
f.registry.base_facts_unvalidated(&beyond).is_none(),
"the refused key is cold/unretained"
);
let first = key(1, "nrpc:n0");
f.registry.install_facts_for_test(first.clone(), facts());
let base = f.registry.base_facts_unvalidated(&first).expect("facts");
f.registry.install_unsensed_pool_for_test(
&first,
Arc::new(ScopedUnsensedRoutePool::for_test(base)),
);
assert!(
f.registry.unsensed_pool_unvalidated(&first).is_some(),
"a retained slot owns its pool publication"
);
f.registry.install_unsensed_pool_for_test(
&beyond,
Arc::new(ScopedUnsensedRoutePool::for_test(facts())),
);
assert!(
f.registry.unsensed_pool_unvalidated(&beyond).is_none(),
"no slot, no cell, no 257th pool — the bound is structural, not \
counted"
);
}
#[test]
fn an_exhausted_identity_space_refuses_deterministically() {
let f = fixture();
let family = f.family();
let _live = family.demand(key(1, "nrpc:a")).expect("a");
let retained = f.registry.retained_slots();
f.registry.inner.lock().next_id = u64::MAX;
assert_eq!(
family.demand(key(1, "nrpc:fresh")).err(),
Some(DemandRefused::IdSpaceExhausted),
"a NEW slot needs a fresh incarnation and cannot have one"
);
assert_eq!(
f.registry.retained_slots(),
retained,
"the refusal retained nothing"
);
assert_eq!(
f.registry.inner.lock().next_id,
u64::MAX,
"and mutated no counter"
);
assert_eq!(
f.registry.new_family().err(),
Some(DemandRefused::IdSpaceExhausted)
);
assert_eq!(f.metrics.refused_id_space_exhausted(), 2);
assert!(
family.demand(key(1, "nrpc:a")).is_ok(),
"sharing a retained slot allocates nothing"
);
}
#[derive(Debug, PartialEq, Eq)]
struct NoEffect {
slots: usize,
pending: usize,
handles: usize,
ids: u64,
retired: u64,
}
fn no_effect(f: &Fixture, family: &RoutingFamily) -> NoEffect {
NoEffect {
slots: f.registry.retained_slots(),
pending: f.registry.pending_slots(),
handles: family.handles(),
ids: f.registry.allocated_ids_for_test(),
retired: f.metrics.slots_retired(),
}
}
fn set(seeds: &[u8], tag: &str) -> Vec<SlotKey> {
seeds.iter().map(|s| key(*s, tag)).collect()
}
#[test]
fn a_demand_set_past_the_family_bound_retains_nothing() {
let f = fixture();
let family = f.family();
let mut held = Vec::new();
for i in 0..62u32 {
held.push(
family
.demand(key(1, &format!("nrpc:fill-{i}")))
.expect("fill"),
);
}
assert_eq!(family.handles(), 62);
let before = no_effect(&f, &family);
assert_eq!(
family.demand_set(set(&[10, 11, 12], "nrpc:wide")).err(),
Some(DemandRefused::FamilyAtCapacity),
"62 + 3 exceeds the 64-handle family budget"
);
assert_eq!(
no_effect(&f, &family),
before,
"a refused set retains no slot, queues no work, spends no handle, \
consumes no identity and retires nothing"
);
assert_eq!(f.metrics.refused_family_at_capacity(), 1);
let fits = family
.demand_set(set(&[10, 11], "nrpc:wide"))
.expect("62 + 2 fits exactly");
assert_eq!(fits.len(), 2);
assert_eq!(family.handles(), 64);
}
#[test]
fn a_demand_set_past_the_node_bound_retains_nothing() {
let f = fixture();
let mut fillers = Vec::new();
let mut held = Vec::new();
for chunk in 0..4u32 {
let filler = f.family();
for i in 0..64u32 {
let n = chunk * 64 + i;
if n == 255 {
break;
}
held.push(
filler
.demand(key(2, &format!("nrpc:node-{n}")))
.expect("fill"),
);
}
fillers.push(filler);
}
assert_eq!(f.registry.retained_slots(), 255);
let family = f.family();
let before = no_effect(&f, &family);
assert_eq!(
family.demand_set(set(&[20, 21], "nrpc:pair")).err(),
Some(DemandRefused::NodeAtCapacity),
"255 + 2 new slots exceeds the 256-slot node bound"
);
assert_eq!(
no_effect(&f, &family),
before,
"the FIRST of the two must not be retained"
);
assert_eq!(f.metrics.refused_node_at_capacity(), 1);
let one = family
.demand_set(set(&[20], "nrpc:pair"))
.expect("255 + 1 fits");
assert_eq!(one.len(), 1);
assert_eq!(f.registry.retained_slots(), 256);
}
#[test]
fn a_demand_set_over_retained_slots_costs_no_node_capacity() {
let f = fixture();
let mut fillers = Vec::new();
let mut held = Vec::new();
for chunk in 0..4u32 {
let filler = f.family();
for i in 0..64u32 {
held.push(
filler
.demand(key(2, &format!("nrpc:node-{}", chunk * 64 + i)))
.expect("fill"),
);
}
fillers.push(filler);
}
assert_eq!(f.registry.retained_slots(), 256, "the node is FULL");
let family = f.family();
let shared = family
.demand_set(vec![key(2, "nrpc:node-0"), key(2, "nrpc:node-1")])
.expect("sharing retained slots needs no node capacity");
assert_eq!(shared.len(), 2);
assert_eq!(f.registry.retained_slots(), 256, "and created nothing");
assert_eq!(f.metrics.refused_node_at_capacity(), 0);
}
#[test]
fn an_exhausted_identity_space_refuses_a_whole_demand_set() {
let f = fixture();
let family = f.family();
let _live = family.demand(key(1, "nrpc:a")).expect("a");
f.registry.exhaust_ids_for_test();
let before = no_effect(&f, &family);
assert_eq!(
family.demand_set(set(&[30, 31], "nrpc:fresh")).err(),
Some(DemandRefused::IdSpaceExhausted),
"two new slots need two incarnations and there are none"
);
assert_eq!(no_effect(&f, &family), before, "and nothing moved");
assert_eq!(f.metrics.refused_id_space_exhausted(), 1);
let shared = family
.demand_set(vec![key(1, "nrpc:a")])
.expect("a retained slot needs no fresh identity");
assert_eq!(shared.len(), 1);
}
#[test]
fn a_superseded_reader_cannot_read_a_retired_incarnations_facts() {
let f = fixture();
let family = f.family();
let old_key = key(1, "nrpc:retire");
let old = family.demand_set(vec![old_key.clone()]).expect("acquired");
f.registry.install_facts_for_test(old_key.clone(), facts());
assert!(
old.base_facts_unvalidated(0).is_some(),
"precondition: the reader can see its own incarnation's facts"
);
let new = old.replace(vec![key(2, "nrpc:retire")]).expect("replaced");
assert_eq!(f.registry.retained_slots(), 1, "the old slot retired");
assert!(
old.base_facts_unvalidated(0).is_none(),
"an old reader must not retain facts from the retired incarnation"
);
drop(new);
}
#[test]
fn a_common_key_reader_follows_the_successors_ownership() {
let f = fixture();
let family = f.family();
let shared = key(1, "nrpc:common");
let old = family
.demand_set(vec![shared.clone(), key(2, "nrpc:common")])
.expect("acquired");
f.registry.install_facts_for_test(shared.clone(), facts());
assert!(old.base_facts_unvalidated(0).is_some());
let new = old.replace(vec![shared.clone()]).expect("replaced");
assert!(
old.base_facts_unvalidated(0).is_some(),
"the common scope is still retained — by the successor — so it still reads"
);
drop(new);
assert!(
old.base_facts_unvalidated(0).is_none(),
"and goes empty the moment the successor releases the last reference"
);
assert_eq!(f.registry.retained_slots(), 0);
}
#[test]
fn a_fresh_demand_after_retirement_gets_a_fresh_cell() {
let f = fixture();
let family = f.family();
let reused = key(1, "nrpc:reused");
let old = family.demand_set(vec![reused.clone()]).expect("acquired");
f.registry.install_facts_for_test(reused.clone(), facts());
assert!(old.base_facts_unvalidated(0).is_some());
let successor = old.replace(vec![key(2, "nrpc:reused")]).expect("replaced");
assert!(old.base_facts_unvalidated(0).is_none());
let fresh = family
.demand_set(vec![reused.clone()])
.expect("re-demanded");
f.registry.install_facts_for_test(reused.clone(), facts());
assert!(
fresh.base_facts_unvalidated(0).is_some(),
"the live incarnation publishes into its own cell"
);
assert!(
old.base_facts_unvalidated(0).is_none(),
"and the stale cell stays empty — a fresh publication cannot reach it"
);
drop((successor, fresh));
}
#[test]
fn a_stale_incarnation_apply_cannot_republish_a_cleared_cell() {
let f = fixture();
let family = f.family();
let contested = key(1, "nrpc:race");
let old = family
.demand_set(vec![contested.clone()])
.expect("acquired");
f.registry
.install_facts_for_test(contested.clone(), facts());
let successor = old.replace(vec![key(2, "nrpc:race")]).expect("replaced");
let fresh = family
.demand_set(vec![contested.clone()])
.expect("re-demanded");
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(
matches!(outcome, ApplyOutcome::Current { .. }),
"{outcome:?}"
);
assert!(
old.base_facts_unvalidated(0).is_none(),
"the dead incarnation's cell is unreachable from the registry"
);
drop((successor, fresh));
}
#[test]
fn a_demand_handle_couples_both_publication_cells() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:pool");
let handle = family.demand(k.clone()).expect("retained");
f.registry.install_facts_for_test(k.clone(), facts());
let base = f.registry.base_facts_unvalidated(&k).expect("facts");
let pool = Arc::new(ScopedUnsensedRoutePool::for_test(base));
f.registry.install_unsensed_pool_for_test(&k, pool.clone());
assert!(
handle.base_facts_unvalidated().is_some(),
"the facts plane reads through the handle"
);
assert!(
handle
.unsensed_pool_unvalidated()
.is_some_and(|read| Arc::ptr_eq(&read, &pool)),
"and the pool plane reads the EXACT published pool — the same \
cell, not a copy taken at demand time"
);
}
#[test]
fn a_demand_set_couples_both_cells_per_contributor() {
let f = fixture();
let family = f.family();
let set = family
.demand_set(vec![key(1, "nrpc:pool"), key(2, "nrpc:pool")])
.expect("acquired");
for k in set.keys().to_vec() {
f.registry.install_facts_for_test(k.clone(), facts());
let base = f.registry.base_facts_unvalidated(&k).expect("facts");
f.registry.install_unsensed_pool_for_test(
&k,
Arc::new(ScopedUnsensedRoutePool::for_test(base)),
);
}
for (index, k) in set.keys().to_vec().iter().enumerate() {
let through_set = set.unsensed_pool_unvalidated(index).expect("pool");
let through_registry = f.registry.unsensed_pool_unvalidated(k).expect("pool");
assert!(
Arc::ptr_eq(&through_set, &through_registry),
"contributor {index} reads its own slot's pool — the planes \
cannot misalign"
);
}
}
#[test]
fn retiring_the_last_reference_clears_both_cells() {
let f = fixture();
let family = f.family();
let old_key = key(1, "nrpc:retire");
let old = family.demand_set(vec![old_key.clone()]).expect("acquired");
f.registry.install_facts_for_test(old_key.clone(), facts());
let base = f.registry.base_facts_unvalidated(&old_key).expect("facts");
f.registry.install_unsensed_pool_for_test(
&old_key,
Arc::new(ScopedUnsensedRoutePool::for_test(base)),
);
assert!(old.unsensed_pool_unvalidated(0).is_some(), "precondition");
let new = old.replace(vec![key(2, "nrpc:retire")]).expect("replaced");
assert!(
old.base_facts_unvalidated(0).is_none() && old.unsensed_pool_unvalidated(0).is_none(),
"a retired incarnation's cells BOTH read empty"
);
drop(new);
}
#[test]
fn a_transfer_leaves_the_common_keys_pool_published() {
let f = fixture();
let family = f.family();
let shared = key(1, "nrpc:common");
let old = family
.demand_set(vec![shared.clone(), key(2, "nrpc:common")])
.expect("acquired");
f.registry.install_facts_for_test(shared.clone(), facts());
let base = f.registry.base_facts_unvalidated(&shared).expect("facts");
let pool = Arc::new(ScopedUnsensedRoutePool::for_test(base));
f.registry
.install_unsensed_pool_for_test(&shared, pool.clone());
let index = old
.keys()
.iter()
.position(|k| *k == shared)
.expect("the set names the shared key");
let new = old.replace(vec![shared.clone()]).expect("replaced");
assert!(
old.unsensed_pool_unvalidated(index)
.is_some_and(|read| Arc::ptr_eq(&read, &pool)),
"the transfer cleared neither plane — the scope is still retained, \
by the successor, and the pool still reads"
);
drop(new);
assert!(
old.unsensed_pool_unvalidated(index).is_none(),
"and both planes go dark when the successor releases the last \
reference"
);
}
#[test]
fn facts_invalidation_clears_the_derived_pool() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:pool");
let _live = family.demand(k.clone()).expect("retained");
f.registry.install_facts_for_test(k.clone(), facts());
let base = f.registry.base_facts_unvalidated(&k).expect("facts");
f.registry
.install_unsensed_pool_for_test(&k, Arc::new(ScopedUnsensedRoutePool::for_test(base)));
f.registry.invalidate_for_test(&k);
assert!(f.registry.base_facts_unvalidated(&k).is_none());
assert!(
f.registry.unsensed_pool_unvalidated(&k).is_none(),
"the pool's basis is gone, so the pool is gone"
);
}
#[test]
fn a_stale_observation_invalidates_neither_plane() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:pool");
let _live = family.demand(k.clone()).expect("retained");
let superseded = facts();
f.registry
.install_facts_for_test(k.clone(), superseded.clone());
f.registry.install_facts_for_test(k.clone(), facts());
let current = f.registry.base_facts_unvalidated(&k).expect("facts");
let pool = Arc::new(ScopedUnsensedRoutePool::for_test(current.clone()));
f.registry.install_unsensed_pool_for_test(&k, pool.clone());
f.registry.invalidate_if_stale(&k, &superseded);
assert!(
f.registry
.base_facts_unvalidated(&k)
.is_some_and(|live| Arc::ptr_eq(&live, ¤t)),
"facts the delayed reader did not observe survive"
);
assert!(
f.registry
.unsensed_pool_unvalidated(&k)
.is_some_and(|read| Arc::ptr_eq(&read, &pool)),
"and so does the pool derived from them"
);
f.registry.invalidate_if_stale(&k, ¤t);
assert!(f.registry.base_facts_unvalidated(&k).is_none());
assert!(f.registry.unsensed_pool_unvalidated(&k).is_none());
}
#[test]
fn installing_newer_facts_clears_the_superseded_pool() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:pool");
let _live = family.demand(k.clone()).expect("retained");
f.registry.install_facts_for_test(k.clone(), facts());
let base = f.registry.base_facts_unvalidated(&k).expect("facts");
f.registry
.install_unsensed_pool_for_test(&k, Arc::new(ScopedUnsensedRoutePool::for_test(base)));
f.registry.install_facts_for_test(k.clone(), facts());
assert!(
f.registry.base_facts_unvalidated(&k).is_some(),
"the newer facts are published"
);
assert!(
f.registry.unsensed_pool_unvalidated(&k).is_none(),
"and the superseded facts' pool is not beside them"
);
}
#[test]
fn a_replacement_successor_stays_index_aligned_across_both_planes() {
let f = fixture();
let family = f.family();
let a = key(1, "nrpc:align");
let b = key(2, "nrpc:align");
let c = key(3, "nrpc:align");
let old = family
.demand_set(vec![a.clone(), b.clone()])
.expect("acquired");
let successor = old.replace(vec![b.clone(), c.clone()]).expect("replaced");
for k in successor.keys().to_vec() {
f.registry.install_facts_for_test(k.clone(), facts());
let base = f.registry.base_facts_unvalidated(&k).expect("facts");
f.registry.install_unsensed_pool_for_test(
&k,
Arc::new(ScopedUnsensedRoutePool::for_test(base)),
);
}
for (index, k) in successor.keys().to_vec().iter().enumerate() {
let facts_via_set = successor.base_facts_unvalidated(index).expect("facts");
let facts_via_registry = f.registry.base_facts_unvalidated(k).expect("facts");
assert!(
Arc::ptr_eq(&facts_via_set, &facts_via_registry),
"successor contributor {index} reads its OWN key's facts"
);
let pool_via_set = successor.unsensed_pool_unvalidated(index).expect("pool");
let pool_via_registry = f.registry.unsensed_pool_unvalidated(k).expect("pool");
assert!(
Arc::ptr_eq(&pool_via_set, &pool_via_registry),
"and its OWN key's pool — the pairing survives a replacement"
);
}
drop(old);
}
#[test]
fn an_actor_pass_publishes_the_pool_it_derived() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:build");
*f.source.rows.lock() = vec![provider_row(7, 42, 9_000), provider_row(8, 43, 4_000)];
let generation = f.source.sessions.publish(
[(entity(7), direct(0xabc))]
.into_iter()
.collect::<BTreeMap<_, _>>(),
);
let handle = family.demand(k.clone()).expect("retained");
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(matches!(outcome, ApplyOutcome::Current { .. }));
let facts = f.registry.base_facts_unvalidated(&k).expect("facts");
let pool = f.registry.unsensed_pool_unvalidated(&k).expect("pool");
assert!(
pool.derives_from(&facts),
"the pool names the EXACT facts artifact published beside it"
);
assert_eq!(pool.key(), &k, "and its own authority-scoped identity");
assert_eq!(pool.authority(), &facts.authority);
assert_eq!(
pool.epoch(),
facts.epoch,
"the exact scoped source vector, not a re-derived one"
);
assert_eq!(pool.provenance(), ProviderProvenance::OwnerPlane);
assert_eq!(pool.session_generation(), generation);
assert_eq!(
pool.earliest_deadline(),
4_000,
"the earliest provider expiry bounds the pool exactly as it bounds \
the facts"
);
assert_eq!(
f.registry.next_artifact_deadline(),
Some(4_000),
"and PRIVATE-DISCOVERY expiry ARMS the actor on it: the pool's \
bound is the artifact's, so one arm covers both planes"
);
let rows = pool.providers();
assert_eq!(rows.len(), 2, "the whole scoped provider vector");
assert_eq!(rows[0].provider, entity(7));
assert_eq!(
rows[0].owner_org,
OrgId::from_bytes([7u8.wrapping_add(0x40); 32]),
"the owner relation the ingest path PROVED, carried through"
);
assert_eq!(rows[0].generation, 42, "per-row announcement provenance");
assert_eq!(rows[0].expires_at, 9_000);
assert_eq!(
rows[0].direct,
direct(0xabc),
"annotated under the ONE captured session view"
);
assert_eq!(
rows[1].direct,
DirectEligibility::Cold,
"a provider the projection does not resolve is COLD, never guessed"
);
assert!(
handle
.unsensed_pool_unvalidated()
.is_some_and(|read| Arc::ptr_eq(&read, &pool)),
"and the lock-free handle reads the very pool the actor published"
);
assert_eq!(f.metrics.pools_published(), 1);
assert_eq!(f.metrics.pools_refused_stale_session(), 0);
}
#[test]
fn an_unserved_reconstruction_publishes_no_pool_but_a_served_empty_one_does() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:unserved");
f.source.sessions.publish(BTreeMap::new());
let _held = family.demand(k.clone()).expect("retained");
f.source.unserved.store(true, Ordering::Release);
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(
f.registry.base_facts_unvalidated(&k).is_some(),
"the Unserved artifact IS published — it is exact structural \
evidence that the source cannot speak for this scope"
);
assert!(
f.registry.unsensed_pool_unvalidated(&k).is_none(),
"but no pool is published over it"
);
f.source.unserved.store(false, Ordering::Release);
f.registry.invalidate_for_test(&k);
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
let pool = f
.registry
.unsensed_pool_unvalidated(&k)
.expect("a served empty bucket is exact evidence and gets a pool");
assert!(pool.providers().is_empty());
}
#[test]
fn a_session_view_that_moved_during_the_build_publishes_no_pool() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:race");
*f.source.rows.lock() = vec![provider_row(7, 1, u64::MAX)];
let captured = f
.source
.sessions
.publish([(entity(7), direct(1))].into_iter().collect());
let _held = family.demand(k.clone()).expect("retained");
let sessions = f.source.clone();
*f.source.during_build.lock() = Some(Box::new(move || {
sessions
.sessions
.publish([(entity(7), direct(2))].into_iter().collect());
}));
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(
matches!(outcome, ApplyOutcome::Progress { .. }),
"the pass made progress and still owes the pool"
);
assert!(
f.registry.base_facts_unvalidated(&k).is_some(),
"the facts are CURRENT — the commit pin proved it, and sessions \
say nothing about discovery"
);
assert!(
f.registry.unsensed_pool_unvalidated(&k).is_none(),
"the pool built under the superseded view is never observable"
);
assert_eq!(f.metrics.pools_published(), 0);
assert_eq!(f.metrics.pools_refused_stale_session(), 1);
assert_eq!(
f.registry.pending_slots(),
1,
"the live slot is re-queued, so the next pass rebuilds the pool"
);
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(matches!(outcome, ApplyOutcome::Current { .. }));
let pool = f.registry.unsensed_pool_unvalidated(&k).expect("pool");
assert!(pool.session_generation() > captured);
assert_eq!(pool.providers()[0].direct, direct(2));
}
#[test]
fn a_source_that_moved_during_the_build_publishes_neither_plane() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:srcrace");
f.source
.sessions
.publish([(entity(7), direct(1))].into_iter().collect());
*f.source.rows.lock() = vec![provider_row(7, 1, u64::MAX)];
let _held = family.demand(k.clone()).expect("retained");
let source = f.source.clone();
*f.source.during_build.lock() = Some(Box::new(move || source.advance()));
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(matches!(outcome, ApplyOutcome::Superseded));
assert!(f.registry.base_facts_unvalidated(&k).is_none());
assert!(f.registry.unsensed_pool_unvalidated(&k).is_none());
assert_eq!(f.metrics.pools_published(), 0);
assert_eq!(f.registry.pending_slots(), 1);
}
#[test]
fn a_pool_cannot_compose_two_session_generations() {
let f = fixture();
let family = f.family();
let a = key(1, "nrpc:mixed");
let b = key(2, "nrpc:mixed");
*f.source.rows.lock() = vec![provider_row(7, 1, u64::MAX)];
f.source
.sessions
.publish([(entity(7), direct(1))].into_iter().collect());
let _held = family
.demand_set(vec![a.clone(), b.clone()])
.expect("retained");
let moved = f.source.clone();
*f.source.during_build.lock() = Some(Box::new(move || {
moved
.sessions
.publish([(entity(7), direct(2))].into_iter().collect());
}));
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert_eq!(
f.source.sessions.observations.load(Ordering::Acquire),
1,
"ONE observation for the whole quantum — there is no second sample \
for a row to be annotated from"
);
assert_eq!(
f.metrics.pools_refused_stale_session(),
2,
"and both slots refuse rather than publishing a mixed observation"
);
assert!(f.registry.unsensed_pool_unvalidated(&a).is_none());
assert!(f.registry.unsensed_pool_unvalidated(&b).is_none());
}
#[test]
fn session_movement_clears_the_pool_and_preserves_the_facts() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:sessmove");
f.source.sessions.publish(BTreeMap::new());
let _held = family.demand(k.clone()).expect("retained");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
let facts = f.registry.base_facts_unvalidated(&k).expect("facts");
assert!(f.registry.unsensed_pool_unvalidated(&k).is_some());
let live = f.source.sessions.publish(BTreeMap::new());
assert_eq!(f.registry.invalidate_session_older_than(live), 1);
assert!(
f.registry
.base_facts_unvalidated(&k)
.is_some_and(|live| Arc::ptr_eq(&live, &facts)),
"the discovery facts are exactly as current as they were"
);
assert!(
f.registry.unsensed_pool_unvalidated(&k).is_none(),
"and only the annotation is gone"
);
assert_eq!(f.registry.pending_slots(), 1);
assert_eq!(f.metrics.pools_invalidated(), 1);
}
#[test]
fn an_obsolete_session_invalidator_cannot_delete_a_newer_pool() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:delayed");
let obsolete = f.source.sessions.publish(BTreeMap::new());
let _held = family.demand(k.clone()).expect("retained");
let newer = f.source.sessions.publish(BTreeMap::new());
assert!(newer > obsolete);
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
let pool = f.registry.unsensed_pool_unvalidated(&k).expect("pool");
assert_eq!(pool.session_generation(), newer);
assert_eq!(
f.registry.invalidate_session_older_than(obsolete),
0,
"the obsolete transition retires nothing"
);
assert!(
f.registry
.unsensed_pool_unvalidated(&k)
.is_some_and(|read| Arc::ptr_eq(&read, &pool)),
"the newer pool survives it"
);
assert_eq!(f.registry.invalidate_session_older_than(newer), 0);
assert!(f
.registry
.unsensed_pool_unvalidated(&k)
.is_some_and(|read| Arc::ptr_eq(&read, &pool)));
let live = f.source.sessions.publish(BTreeMap::new());
assert_eq!(f.registry.invalidate_session_older_than(live), 1);
assert!(f.registry.unsensed_pool_unvalidated(&k).is_none());
}
#[test]
fn session_movement_does_not_requeue_a_slot_with_no_pool() {
let f = fixture();
let family = f.family();
let cold = key(1, "nrpc:nopool");
let warm = key(2, "nrpc:nopool");
f.source.sessions.publish(BTreeMap::new());
let _held = family
.demand_set(vec![cold.clone(), warm.clone()])
.expect("retained");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
f.registry.take_pool_for_test(&cold);
assert_eq!(f.registry.pending_slots(), 0, "precondition");
let live = f.source.sessions.publish(BTreeMap::new());
assert_eq!(
f.registry.invalidate_session_older_than(live),
1,
"only the slot that HAD a superseded pool is retired"
);
assert_eq!(
f.registry.pending_slots(),
1,
"and only that slot is re-queued — a pool-less slot's rebuild is \
already owed or already in flight"
);
}
#[test]
fn an_exhausted_session_generation_publishes_no_pool_without_spinning() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:spent");
f.source.sessions.publish(BTreeMap::new());
let _held = family.demand(k.clone()).expect("retained");
f.source.sessions.currentness.exhaust();
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(
matches!(outcome, ApplyOutcome::Current { .. }),
"the pass is COMPLETE: it owes no pool it could ever build"
);
assert!(f.registry.base_facts_unvalidated(&k).is_some());
assert!(f.registry.unsensed_pool_unvalidated(&k).is_none());
assert_eq!(
f.registry.pending_slots(),
0,
"nothing is re-queued, so nothing spins"
);
assert_eq!(
f.metrics.pools_refused_stale_session(),
0,
"and it is not counted as a refused RACE — nothing raced"
);
}
#[test]
fn no_reader_can_observe_a_pool_beside_foreign_facts() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:interleave");
f.source.sessions.publish(BTreeMap::new());
let handle = family.demand(k.clone()).expect("retained");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(
f.registry.unsensed_pool_unvalidated(&k).is_some(),
"precondition: a superseded pool must be published when the second \
installation begins, or every gap is trivially pool-free"
);
let observed: Arc<parking_lot::Mutex<Vec<(PublicationGap, bool, bool)>>> =
Arc::new(parking_lot::Mutex::new(Vec::new()));
{
let observed = observed.clone();
let handle_facts = handle.cells.facts.clone();
let handle_pool = handle.cells.unsensed.clone();
f.registry
.observe_publication_for_test(Arc::new(move |gap| {
let facts = handle_facts.load_full();
let pool = handle_pool.load_full();
let paired = match (&facts, &pool) {
(Some(facts), Some(pool)) => pool.derives_from(facts),
(_, None) => true,
(None, Some(_)) => false,
};
observed.lock().push((gap, pool.is_some(), paired));
}));
}
f.registry.requeue_for_test(&k);
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
let observed = observed.lock().clone();
assert_eq!(
observed.len(),
2,
"both gaps must be observed — a witness that samples one proves \
half the invariant"
);
assert!(
observed.iter().all(|(_, _, paired)| *paired),
"no reader observed a pool beside facts it was not derived from: \
{observed:?}"
);
assert!(
observed.iter().all(|(_, pool_present, _)| !*pool_present),
"and every intermediate state is a COLD-POOL state, which is the \
state a reader already has to handle: {observed:?}"
);
let final_pool = f.registry.unsensed_pool_unvalidated(&k).expect("pool");
let final_facts = f.registry.base_facts_unvalidated(&k).expect("facts");
assert!(final_pool.derives_from(&final_facts));
}
#[test]
fn an_authority_deadline_with_zero_providers_retires_both_planes_and_rearms() {
let f = fixture();
let family = f.family();
let k = key(1, "nrpc:deadline");
f.source.sessions.publish(BTreeMap::new());
f.source.authority_deadline.store(1_000, Ordering::Release);
let _held = family.demand(k.clone()).expect("retained");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
let pool = f.registry.unsensed_pool_unvalidated(&k).expect("pool");
assert!(
pool.providers().is_empty(),
"zero rows: the authority deadline is the only one there is"
);
assert_eq!(pool.earliest_deadline(), 1_000);
assert_eq!(
f.registry.next_artifact_deadline(),
Some(1_000),
"and the actor ARMS on it"
);
assert_eq!(f.registry.retire_expired(1_000), 1);
assert!(f.registry.base_facts_unvalidated(&k).is_none());
assert!(
f.registry.unsensed_pool_unvalidated(&k).is_none(),
"the pool goes with the facts it derived from"
);
assert_eq!(f.registry.pending_slots(), 1, "the rebuild is armed");
f.source.unserved.store(true, Ordering::Release);
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert_eq!(f.registry.next_artifact_deadline(), None);
assert_eq!(f.registry.pending_slots(), 0);
}
#[test]
fn the_two_hundred_fifty_seventh_slot_can_publish_no_pool() {
let f = fixture();
f.source.sessions.publish(BTreeMap::new());
let mut held = Vec::new();
for index in 0..MAX_NODE_SLOTS {
let family = f.family();
let key = key(1, &format!("nrpc:cap{index}"));
held.push(family.demand(key).expect("within the node bound"));
}
assert_eq!(f.registry.retained_slots(), MAX_NODE_SLOTS);
let refused = key(1, "nrpc:cap256");
let overflow = f.family();
assert_eq!(
overflow.demand(refused.clone()).err(),
Some(DemandRefused::NodeAtCapacity)
);
for _ in 0..16 {
if f.registry.pending_slots() == 0 {
break;
}
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
}
assert_eq!(f.metrics.pools_published(), MAX_NODE_SLOTS as u64);
assert!(
f.registry.unsensed_pool_unvalidated(&refused).is_none(),
"the refused slot owns no cell, so no pool can exist for it"
);
assert_eq!(f.registry.retained_slots(), MAX_NODE_SLOTS);
}
#[test]
fn release_one_cannot_decrement_a_reference_a_family_does_not_hold() {
let f = fixture();
let owner = f.family();
let stranger = f.family();
let owned = key(1, "nrpc:owned");
let held = owner.demand_set(vec![owned.clone()]).expect("acquired");
let before = f.registry.retained_slots();
let generation = f.registry.node_capacity_generation();
f.registry.release_one_for_test(&stranger, &owned);
assert_eq!(
f.registry.retained_slots(),
before,
"a family that holds nothing gives nothing back"
);
assert_eq!(f.registry.node_capacity_generation(), generation);
assert_eq!(owner.handles(), 1, "the owner still holds its handle");
assert!(
held.base_facts_unvalidated(0).is_some() || f.registry.retained_slots() == 1,
"and its slot survives"
);
drop(held);
assert_eq!(
f.registry.retained_slots(),
0,
"the owner can still release"
);
}
#[test]
fn an_already_transferred_set_cannot_be_replaced_again() {
let f = fixture();
let family = f.family();
let old = family
.demand_set(vec![key(1, "nrpc:once")])
.expect("acquired");
let successor = old
.replace(vec![key(2, "nrpc:once")])
.expect("first replacement");
let handles = family.handles();
let slots = f.registry.retained_slots();
assert_eq!(
old.replace(vec![key(3, "nrpc:once")]).err(),
Some(ReplaceRefused::Superseded),
"a spent set is not the basis of anything"
);
assert_eq!(family.handles(), handles, "and nothing moved");
assert_eq!(f.registry.retained_slots(), slots);
drop(successor);
}
#[test]
fn duplicate_keys_in_a_demand_set_collapse() {
let f = fixture();
let family = f.family();
let handles = family
.demand_set(vec![
key(1, "nrpc:dup"),
key(1, "nrpc:dup"),
key(2, "nrpc:dup"),
key(1, "nrpc:dup"),
])
.expect("acquired");
assert_eq!(handles.len(), 2, "four keys, two distinct scopes");
assert_eq!(family.handles(), 2, "and two handles against the budget");
assert_eq!(f.registry.retained_slots(), 2);
assert_eq!(
f.registry.allocated_ids_for_test(),
3,
"one identity for the family and one per distinct slot — not per key"
);
}
#[test]
fn a_refusal_after_identities_are_considered_consumes_none() {
let f = fixture();
let family = f.family();
let mut held = Vec::new();
for i in 0..63u32 {
held.push(
family
.demand(key(1, &format!("nrpc:fill-{i}")))
.expect("fill"),
);
}
let before = no_effect(&f, &family);
assert_eq!(before.handles, 63);
assert_eq!(
family.demand_set(set(&[40, 41, 42], "nrpc:late")).err(),
Some(DemandRefused::FamilyAtCapacity)
);
let after = no_effect(&f, &family);
assert_eq!(
after.ids, before.ids,
"the identity space is untouched — the component a loop leaks"
);
assert_eq!(
after.retired, before.retired,
"and nothing was created only to be retired again"
);
assert_eq!(after, before, "totally, not just in those two components");
}
#[test]
fn a_successful_demand_set_queues_every_key_and_marks_once() {
let f = fixture();
let family = f.family();
let handles = family
.demand_set(set(&[50, 51, 52], "nrpc:batch"))
.expect("acquired");
assert_eq!(handles.len(), 3);
assert_eq!(f.registry.pending_slots(), 3, "every key owes work");
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(
matches!(outcome, ApplyOutcome::Current { .. }),
"{outcome:?}"
);
for seed in [50u8, 51, 52] {
assert!(
f.registry
.base_facts_unvalidated(&key(seed, "nrpc:batch"))
.is_some(),
"the whole set is warmed by ONE pass"
);
}
}
#[test]
fn a_demand_set_is_ordered_owner_scopes_first() {
let f = fixture();
let family = f.family();
let grant = PrivateAudienceScope::new(CapabilityAudienceScope::Grant {
grant_id: [9u8; 32],
audience_handle: [9u8; 32],
})
.expect("grant scopes are private");
let cap = CapabilityAuthorityId::for_tag("nrpc:order");
let handles = family
.demand_set(vec![
SlotKey {
scope: grant.clone(),
capability: cap,
},
key(1, "nrpc:order"),
])
.expect("acquired");
assert_eq!(handles.keys()[0], key(1, "nrpc:order"), "Owner first");
assert_eq!(handles.keys()[1].scope, grant, "Grant after");
}
#[test]
fn only_the_last_reference_retires_the_slot() {
let f = fixture();
let a = f.family().demand(key(1, "nrpc:a")).expect("a");
let b = f.family().demand(key(1, "nrpc:a")).expect("b");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(f
.registry
.base_facts_unvalidated(&key(1, "nrpc:a"))
.is_some());
drop(a);
assert_eq!(f.registry.retained_slots(), 1, "one reference remains");
assert!(f
.registry
.base_facts_unvalidated(&key(1, "nrpc:a"))
.is_some());
drop(b);
assert_eq!(
f.registry.retained_slots(),
0,
"the last reference retired it"
);
assert_eq!(f.metrics.slots_retired(), 1);
assert!(f
.registry
.base_facts_unvalidated(&key(1, "nrpc:a"))
.is_none());
}
#[test]
fn a_late_build_cannot_resurrect_a_replaced_slot_incarnation() {
let f = fixture();
let target = key(1, "nrpc:a");
let original = f.family();
let successor = f.family();
let held: Arc<parking_lot::Mutex<Option<DemandHandle>>> = Arc::new(
parking_lot::Mutex::new(Some(original.demand(target.clone()).expect("first demand"))),
);
let first_incarnation = f
.registry
.inner
.lock()
.slots
.get(&target)
.expect("retained")
.incarnation;
let recreated: Arc<parking_lot::Mutex<Option<DemandHandle>>> =
Arc::new(parking_lot::Mutex::new(None));
{
let held = held.clone();
let recreated = recreated.clone();
let successor = successor.clone();
let target = target.clone();
*f.source.during_build.lock() = Some(Box::new(move || {
drop(held.lock().take());
*recreated.lock() = Some(successor.demand(target.clone()).expect("re-demand"));
}));
}
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert_eq!(
outcome,
ApplyOutcome::Superseded,
"slot movement supersedes the attempt"
);
assert!(
f.registry.base_facts_unvalidated(&target).is_none(),
"the artifact for the dead incarnation was discarded, not installed"
);
assert_eq!(f.metrics.discarded_obsolete(), 1);
assert_eq!(f.metrics.installs(), 0);
assert_eq!(f.metrics.slots_retired(), 1);
let inner = f.registry.inner.lock();
let slot = inner.slots.get(&target).expect("recreated slot retained");
assert_ne!(
slot.incarnation, first_incarnation,
"the recreated slot has a FRESH identity"
);
assert!(
inner
.slots_by_capability
.get(&target.capability)
.is_some_and(|bucket| bucket.contains(&target)),
"and is still indexed by capability"
);
assert!(
inner.pending.contains(&target),
"the live incarnation still owes work, queued authoritatively"
);
drop(inner);
assert!(recreated.lock().is_some());
}
#[test]
fn a_new_incarnation_invalidates_every_retained_slot() {
let f = fixture();
let family = f.family();
let _a = family.demand(key(1, "nrpc:a")).expect("a");
let _b = family.demand(key(1, "nrpc:b")).expect("b");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(f
.registry
.base_facts_unvalidated(&key(1, "nrpc:a"))
.is_some());
assert_eq!(f.registry.pending_slots(), 0);
f.registry.deactivate_incarnation(1);
f.registry.activate_incarnation(2);
assert!(
f.registry
.base_facts_unvalidated(&key(1, "nrpc:a"))
.is_none(),
"nothing a dead incarnation built stays readable"
);
assert_eq!(
f.registry.pending_slots(),
2,
"every retained slot re-queued"
);
}
#[test]
fn a_stale_actor_neither_consumes_pending_work_nor_reports_current() {
let f = fixture();
let _held = f.family().demand(key(1, "nrpc:a")).expect("a");
assert_eq!(f.registry.pending_slots(), 1);
f.source.reset();
let outcome = f
.registry
.apply(2, request(true, DirtyCapabilities::RebuildAll));
assert_eq!(outcome, ApplyOutcome::Superseded);
assert!(
f.source.queries().is_empty(),
"a stale actor never even queries the source"
);
assert_eq!(
f.registry.pending_slots(),
1,
"the authoritative work is still owed"
);
assert_eq!(f.metrics.stale_actor_rejections(), 1);
f.registry.deactivate_incarnation(1);
assert_eq!(
f.registry.apply(1, request(true, DirtyCapabilities::Clean)),
ApplyOutcome::Superseded
);
assert_eq!(f.registry.pending_slots(), 1);
assert_eq!(f.metrics.stale_actor_rejections(), 2);
f.registry.activate_incarnation(3);
let outcome = f.registry.apply(3, request(true, DirtyCapabilities::Clean));
assert!(matches!(outcome, ApplyOutcome::Current { .. }));
assert_eq!(f.source.queries(), vec![key(1, "nrpc:a")]);
}
#[test]
fn an_actor_revoked_after_selection_cannot_settle_an_empty_pass_as_current() {
let f = fixture();
assert_eq!(
f.registry
.apply(1, request(false, DirtyCapabilities::RebuildAll)),
ApplyOutcome::Current {
source_generation: f.source.generation()
},
"a full request over no retained slots completes"
);
let f = fixture();
{
let registry = f.registry.clone();
*f.source.on_snapshot.lock() = Some(Box::new(move || {
registry.deactivate_incarnation(1);
}));
}
let outcome = f
.registry
.apply(1, request(false, DirtyCapabilities::RebuildAll));
assert_eq!(
outcome,
ApplyOutcome::Superseded,
"an actor revoked after phase 1 cannot settle Current"
);
assert_eq!(f.metrics.stale_actor_rejections(), 1);
let f = fixture();
let target = key(1, "nrpc:a");
let _held = f.family().demand(target.clone()).expect("a");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert_eq!(f.registry.pending_slots(), 0, "nothing left to select");
{
let registry = f.registry.clone();
*f.source.on_snapshot.lock() = Some(Box::new(move || {
registry.deactivate_incarnation(1);
}));
}
assert_eq!(
f.registry.apply(1, request(true, DirtyCapabilities::Clean)),
ApplyOutcome::Superseded
);
assert_eq!(f.metrics.stale_actor_rejections(), 1);
}
#[test]
fn authority_revoked_during_a_build_requeues_every_live_slot() {
let f = fixture();
let family = f.family();
let a = key(1, "nrpc:a");
let b = key(1, "nrpc:b");
let _ha = family.demand(a.clone()).expect("a");
let hb = family.demand(b.clone()).expect("b");
let registry = f.registry.clone();
let hb_cell: Arc<parking_lot::Mutex<Option<DemandHandle>>> =
Arc::new(parking_lot::Mutex::new(Some(hb)));
{
let hb_cell = hb_cell.clone();
*f.source.during_build.lock() = Some(Box::new(move || {
registry.deactivate_incarnation(1);
drop(hb_cell.lock().take());
}));
}
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert_eq!(outcome, ApplyOutcome::Superseded);
assert_eq!(
f.metrics.installs(),
0,
"nothing from a revoked actor lands"
);
assert_eq!(f.metrics.stale_actor_rejections(), 1);
let inner = f.registry.inner.lock();
assert!(inner.pending.contains(&a), "the live slot still owes work");
assert!(
!inner.pending.contains(&b),
"a retired slot is not resurrected into the queue"
);
}
#[test]
fn a_caps_delta_invalidates_affected_facts_before_the_rebuild_begins() {
let f = fixture();
let family = f.family();
let c = key(1, "nrpc:c");
let d = key(1, "nrpc:d");
let _hc = family.demand(c.clone()).expect("c");
let _hd = family.demand(d.clone()).expect("d");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(f.registry.base_facts_unvalidated(&c).is_some());
assert!(f.registry.base_facts_unvalidated(&d).is_some());
let observed = Arc::new(AtomicBool::new(false));
{
let registry = f.registry.clone();
let observed = observed.clone();
let c = c.clone();
let d = d.clone();
*f.source.during_build.lock() = Some(Box::new(move || {
assert!(
registry.base_facts_unvalidated(&c).is_none(),
"C's stale facts must already be gone while C rebuilds"
);
assert!(
registry.base_facts_unvalidated(&d).is_some(),
"D was not named by the delta and keeps its facts"
);
observed.store(true, Ordering::Release);
}));
}
f.source.reset();
f.registry.apply(1, request(false, caps(&["nrpc:c"])));
assert!(observed.load(Ordering::Acquire), "the hook must have run");
assert_eq!(f.source.queries(), vec![c.clone()]);
assert!(
f.registry.base_facts_unvalidated(&c).is_some(),
"and is rebuilt after"
);
}
#[test]
fn caps_invalidates_affected_slots_beyond_the_quantum() {
let f = fixture();
let mut family = f.family();
let mut keys = Vec::new();
let mut held = Vec::new();
for index in 0..(APPLY_QUANTUM + 8) {
if index > 0 && index % MAX_HANDLES_PER_FAMILY == 0 {
family = f.family();
}
let k = key(1, &format!("nrpc:q{index}"));
held.push(family.demand(k.clone()).expect("demanded"));
keys.push(k);
}
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(keys
.iter()
.all(|k| f.registry.base_facts_unvalidated(k).is_some()));
let tags: Vec<String> = (0..(APPLY_QUANTUM + 8))
.map(|index| format!("nrpc:q{index}"))
.collect();
let all: Vec<&str> = tags.iter().map(String::as_str).collect();
f.source.reset();
let outcome = f.registry.apply(1, request(false, caps(&all)));
assert_eq!(
f.source.queries().len(),
APPLY_QUANTUM,
"only one quantum is rebuilt"
);
assert!(
matches!(outcome, ApplyOutcome::Progress { .. }),
"work remains, so this is not a complete installation"
);
assert_eq!(
keys.iter()
.filter(|k| f.registry.base_facts_unvalidated(k).is_some())
.count(),
APPLY_QUANTUM,
"EVERY affected slot was invalidated; only the quantum was rebuilt"
);
assert_eq!(f.registry.pending_slots(), 8);
}
#[test]
fn sustained_source_movement_across_a_multi_quantum_recapture_loses_no_identity() {
let f = fixture();
let mut family = f.family();
let mut held = Vec::new();
let mut keys = Vec::new();
let total = APPLY_QUANTUM + 1;
for index in 0..total {
if index > 0 && index % MAX_HANDLES_PER_FAMILY == 0 {
family = f.family();
}
let slot = key(1, &format!("nrpc:m{index:03}"));
held.push(family.demand(slot.clone()).expect("demanded"));
keys.push(slot);
}
assert_eq!(f.registry.pending_slots(), total);
for pass in 0..6 {
let state = f.source.clone();
*f.source.during_build.lock() = Some(Box::new(move || state.advance()));
assert_eq!(
f.registry
.apply(1, request(true, DirtyCapabilities::RebuildAll)),
ApplyOutcome::Superseded,
"pass {pass}: a pin that refused installs nothing"
);
assert_eq!(
f.registry.pending_slots(),
total,
"pass {pass}: EVERY identity stays owed — a dropped one would leave \
its slot cold with nothing to rebuild it"
);
assert!(
keys.iter()
.all(|k| f.registry.base_facts_unvalidated(k).is_none()),
"pass {pass}: and nothing obsolete was installed"
);
}
let mut outcome = ApplyOutcome::Superseded;
for _ in 0..8 {
outcome = f
.registry
.apply(1, request(true, DirtyCapabilities::RebuildAll));
if matches!(outcome, ApplyOutcome::Current { .. }) {
break;
}
}
assert!(
matches!(outcome, ApplyOutcome::Current { .. }),
"a settled source converges (last outcome {outcome:?})"
);
assert_eq!(f.registry.pending_slots(), 0);
assert!(
keys.iter()
.all(|k| f.registry.base_facts_unvalidated(k).is_some()),
"and every slot the recapture covered is warm — no hole under a Current"
);
}
#[test]
fn sustained_low_sorting_churn_cannot_starve_a_high_sorting_slot() {
let f = fixture();
let mut family = f.family();
let mut held = Vec::new();
let mut entries: Vec<(SlotKey, String)> = Vec::new();
for index in 0..=APPLY_QUANTUM {
if index > 0 && index % MAX_HANDLES_PER_FAMILY == 0 {
family = f.family();
}
let tag = format!("nrpc:q{index:03}");
let slot = key(1, &tag);
held.push(family.demand(slot.clone()).expect("demanded"));
entries.push((slot, tag));
}
entries.sort_by(|a, b| a.0.cmp(&b.0));
let victim = entries.last().expect("victim").0.clone();
let churning: Vec<&str> = entries[..APPLY_QUANTUM]
.iter()
.map(|(_, tag)| tag.as_str())
.collect();
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(f.registry.base_facts_unvalidated(&victim).is_some());
f.registry.invalidate_for_test(&victim);
let mut served_on = None;
for pass in 0..4 {
f.source.reset();
f.registry.apply(1, request(true, caps(&churning)));
assert_eq!(
f.source.queries().len(),
APPLY_QUANTUM,
"pass {pass}: the quantum is saturated, so this is genuine contention \
rather than a pass with room to spare"
);
if f.registry.base_facts_unvalidated(&victim).is_some() {
served_on = Some(pass);
break;
}
}
assert!(
served_on.is_some(),
"the highest-sorting slot must come round: without rotation the churn \
below it wins every pass, forever"
);
}
#[test]
fn caps_touches_only_its_bucket_and_rebuild_all_touches_every_slot() {
let f = fixture();
let family = f.family();
let _a = family.demand(key(1, "nrpc:a")).expect("a");
let _b = family.demand(key(1, "nrpc:b")).expect("b");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
f.source.reset();
f.registry.apply(1, request(false, caps(&["nrpc:b"])));
assert_eq!(f.source.queries(), vec![key(1, "nrpc:b")]);
f.source.reset();
f.registry
.apply(1, request(false, DirtyCapabilities::RebuildAll));
assert_eq!(f.source.queries().len(), 2, "every retained slot");
f.source.reset();
f.registry.apply(1, request(false, caps(&["nrpc:absent"])));
assert!(
f.source.queries().is_empty(),
"an undemanded capability is never projected"
);
}
#[test]
fn combined_source_and_registry_work_deduplicates_a_slot() {
let f = fixture();
let target = key(1, "nrpc:a");
let _held = f.family().demand(target.clone()).expect("a");
assert_eq!(
f.registry.pending_slots(),
1,
"registry work owes this slot"
);
f.source.reset();
f.registry.apply(1, request(true, caps(&["nrpc:a"])));
assert_eq!(
f.source.queries(),
vec![target],
"named by both domains, built once"
);
}
#[test]
fn a_multi_quantum_recapture_reports_progress_until_it_completes() {
let f = fixture();
let mut family = f.family();
let mut keys = Vec::new();
let mut held = Vec::new();
for index in 0..(APPLY_QUANTUM + 10) {
if index > 0 && index % MAX_HANDLES_PER_FAMILY == 0 {
family = f.family();
}
let k = key(1, &format!("nrpc:q{index}"));
held.push(family.demand(k.clone()).expect("demanded"));
keys.push(k);
}
f.source.reset();
let first = f
.registry
.apply(1, request(false, DirtyCapabilities::RebuildAll));
assert_eq!(
f.source.queries().len(),
APPLY_QUANTUM,
"at most one quantum per synchronous application"
);
assert!(
matches!(first, ApplyOutcome::Progress { .. }),
"an incomplete recapture must NOT claim a current installation"
);
assert_eq!(
f.registry.pending_slots(),
10,
"the remainder lives in the registry, not in the wake flag"
);
f.source.reset();
let second = f
.registry
.apply(1, request(true, DirtyCapabilities::RebuildAll));
assert_eq!(
f.source.queries().len(),
10,
"the epoch resumed where it left off"
);
assert!(
matches!(second, ApplyOutcome::Current { .. }),
"the final quantum completes the recapture"
);
assert_eq!(f.registry.pending_slots(), 0);
let generation = f.source.generation();
for k in &keys {
let facts = f.registry.base_facts_unvalidated(k).expect("built");
assert_eq!(facts.actor_incarnation, 1);
assert_eq!(facts.epoch.generation, generation);
}
assert!(!f.registry.inner.lock().recapture_open, "the epoch closed");
}
#[test]
fn a_recapture_restarts_when_the_source_generation_moves_between_quanta() {
let f = fixture();
let mut family = f.family();
let mut held = Vec::new();
for index in 0..(APPLY_QUANTUM + 4) {
if index > 0 && index % MAX_HANDLES_PER_FAMILY == 0 {
family = f.family();
}
held.push(
family
.demand(key(1, &format!("nrpc:q{index}")))
.expect("demanded"),
);
}
let first = f
.registry
.apply(1, request(false, DirtyCapabilities::RebuildAll));
assert!(matches!(first, ApplyOutcome::Progress { .. }));
assert_eq!(f.registry.pending_slots(), 4);
f.source.advance();
let second = f
.registry
.apply(1, request(true, DirtyCapabilities::RebuildAll));
assert!(
matches!(second, ApplyOutcome::Progress { .. }),
"the restart cannot complete in one quantum"
);
assert_eq!(f.metrics.recaptures_restarted(), 1);
assert_eq!(
f.registry.pending_slots(),
APPLY_QUANTUM,
"the 64 slots built against the OLD generation went back on the queue"
);
let third = f
.registry
.apply(1, request(true, DirtyCapabilities::RebuildAll));
assert!(matches!(third, ApplyOutcome::Current { .. }));
let generation = f.source.generation();
assert!(
f.registry.inner.lock().slots.values().all(|slot| slot
.cells
.facts
.load()
.as_ref()
.is_some_and(|facts| facts.epoch.generation == generation)),
"ONE coherent source generation across the whole retained set"
);
}
#[test]
fn ordinary_caps_at_a_newer_generation_reports_current() {
let f = fixture();
let family = f.family();
let c = key(1, "nrpc:c");
let d = key(1, "nrpc:d");
let _hc = family.demand(c.clone()).expect("c");
let _hd = family.demand(d.clone()).expect("d");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
let first = f.source.generation();
f.source.advance();
let outcome = f.registry.apply(1, request(false, caps(&["nrpc:c"])));
let second = f.source.generation();
assert_ne!(first, second);
assert_eq!(
f.registry
.base_facts_unvalidated(&c)
.expect("c rebuilt")
.epoch
.generation,
second
);
assert_eq!(
f.registry
.base_facts_unvalidated(&d)
.expect("d untouched")
.epoch
.generation,
first,
"an unrelated slot legitimately keeps its older stamp"
);
assert_eq!(f.registry.pending_slots(), 0, "no work is owed");
assert_eq!(
outcome,
ApplyOutcome::Current {
source_generation: second
},
"the pass rebuilt everything it was asked to; that IS complete"
);
}
#[test]
fn first_demand_at_a_newer_generation_reports_current() {
let f = fixture();
let family = f.family();
let established = key(1, "nrpc:a");
let _ha = family.demand(established.clone()).expect("a");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
let first = f.source.generation();
f.source.advance();
let fresh = key(1, "nrpc:b");
let _hb = family.demand(fresh.clone()).expect("b");
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
let second = f.source.generation();
assert_eq!(
f.registry
.base_facts_unvalidated(&fresh)
.expect("built")
.epoch
.generation,
second
);
assert_eq!(
f.registry
.base_facts_unvalidated(&established)
.expect("retained")
.epoch
.generation,
first,
"the unrelated retained slot was not rebuilt and did not need to be"
);
assert_eq!(f.registry.pending_slots(), 0);
assert_eq!(
outcome,
ApplyOutcome::Current {
source_generation: second
}
);
}
#[test]
fn progress_always_implies_owed_work() {
let f = fixture();
let mut family = f.family();
let mut held = Vec::new();
for index in 0..(APPLY_QUANTUM + 3) {
if index > 0 && index % MAX_HANDLES_PER_FAMILY == 0 {
family = f.family();
}
held.push(
family
.demand(key(1, &format!("nrpc:q{index}")))
.expect("demanded"),
);
}
for pass in 0..4 {
let outcome = f
.registry
.apply(1, request(true, DirtyCapabilities::RebuildAll));
let owed = f.registry.pending_slots();
match outcome {
ApplyOutcome::Progress { .. } => assert!(
owed > 0,
"pass {pass}: Progress with nothing owed strands the actor"
),
ApplyOutcome::Current { .. } => assert_eq!(owed, 0, "pass {pass}"),
other => panic!("pass {pass}: unexpected {other:?}"),
}
}
}
#[test]
fn a_mutation_during_reconstruction_defeats_the_commit_pin_without_waiting() {
let f = fixture();
let target = key(1, "nrpc:a");
let _held = f.family().demand(target.clone()).expect("a");
let moved = Arc::new(AtomicBool::new(false));
{
let source = f.source.clone();
let moved = moved.clone();
*f.source.during_build.lock() = Some(Box::new(move || {
let source = source.clone();
let advanced = std::thread::spawn(move || match source.gate.try_lock() {
Some(mut generation) => {
*generation += 1;
true
}
None => false,
})
.join()
.expect("mutation thread");
assert!(
advanced,
"a rival mutation must not have to wait on reconstruction"
);
moved.store(true, Ordering::Release);
}));
}
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(moved.load(Ordering::Acquire), "the mutation must have run");
assert_eq!(outcome, ApplyOutcome::Superseded);
assert_eq!(f.metrics.installs(), 0, "nothing stale installed");
assert!(f.registry.base_facts_unvalidated(&target).is_none());
assert_eq!(
f.registry.pending_slots(),
1,
"the live slot re-entered the authoritative queue"
);
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert_eq!(
outcome,
ApplyOutcome::Current {
source_generation: f.source.generation()
}
);
}
#[test]
fn the_commit_pin_outlives_the_installation() {
let f = fixture();
let target = key(1, "nrpc:a");
let _held = f.family().demand(target.clone()).expect("a");
let observed = Arc::new(AtomicBool::new(false));
{
let registry = f.registry.clone();
let metrics = f.metrics.clone();
let observed = observed.clone();
let target = target.clone();
*f.source.on_commit_release.lock() = Some(Arc::new(move || {
assert_eq!(
metrics.installs(),
1,
"the commit pin must still be held when the facts are installed"
);
assert!(registry.base_facts_unvalidated(&target).is_some());
observed.store(true, Ordering::Release);
}));
}
let outcome = f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert!(
observed.load(Ordering::Acquire),
"the commit pin must have dropped"
);
let generation = f.source.generation();
assert_eq!(
outcome,
ApplyOutcome::Current {
source_generation: generation
}
);
assert_eq!(
f.registry
.base_facts_unvalidated(&target)
.expect("built")
.epoch
.generation,
generation,
"facts carry exactly the generation the commit pin proved current"
);
}
#[test]
fn neither_lock_is_held_across_the_snapshot_or_reconstruction() {
let f = fixture();
let _held = f.family().demand(key(1, "nrpc:a")).expect("a");
f.registry.apply(1, request(true, DirtyCapabilities::Clean));
assert_eq!(f.source.queries(), vec![key(1, "nrpc:a")]);
assert_eq!(
f.source.snapshots.load(Ordering::Acquire),
1,
"one brief capture per quantum"
);
}
}