Query Reliability
Distributed queries need two separate reliability decisions:
- which replica should answer each requested range
- whether the combined response is complete or partial
Scepter keeps those decisions explicit.
Replica Resolution
ReplicaResolver groups candidates by target range, removes unavailable
replicas, chooses the strongest primary, and keeps ordered fallbacks.
use scepter::{
ReplicaCandidate, ReplicaQuality, ReplicaResolver, ReplicaState,
};
let resolved = ReplicaResolver::with_max_fallbacks(1).resolve(vec![
ReplicaCandidate::new(
b"a".to_vec()..b"m".to_vec(),
"leaf-a",
ReplicaQuality::new(0, 60, 60, 60, true, ReplicaState::Available),
),
ReplicaCandidate::new(
b"a".to_vec()..b"m".to_vec(),
"leaf-b",
ReplicaQuality::new(0, 60, 55, 60, true, ReplicaState::Recovering),
),
]);
assert_eq!(resolved[0].primary, "leaf-a");
assert_eq!(resolved[0].fallbacks, vec!["leaf-b"]);
Query Health
QueryHealth records child completion and degradation metadata. Issue-only
responses can be complete by count while still partial by quality.
use scepter::{IssueKind, QueryHealth};
let mut health = QueryHealth::with_expected_children(2);
health.record_completed();
health.push_issue("zone-west", IssueKind::PrunedZone, "soft deadline elapsed");
assert!(health.is_partial());
assert_eq!(health.completeness(), 0.5);