This commit is contained in:
Alexey
2026-09-25 19:46:31 +03:00
parent 2d63fcf376
commit 326c0ecdb9
128 changed files with 914 additions and 1248 deletions
+5 -18
View File
@@ -290,11 +290,8 @@ impl Drop for UserIpPermit {
let Some(owner) = self.owner.take() else {
return;
};
self.tracker.enqueue_cleanup_for_incarnation(
owner.user,
owner.incarnation,
owner.ip,
);
self.tracker
.enqueue_cleanup_for_incarnation(owner.user, owner.incarnation, owner.ip);
}
}
@@ -338,9 +335,7 @@ impl UserConnectionReservation {
stats_observation: Option<UserConnectionObservation>,
tracks_ip: bool,
) -> Self {
let ip_permit = tracks_ip.then(|| {
UserIpPermit::new(ip_tracker, user, incarnation, ip)
});
let ip_permit = tracks_ip.then(|| UserIpPermit::new(ip_tracker, user, incarnation, ip));
Self {
stats,
quota_handle,
@@ -388,12 +383,7 @@ pub(crate) async fn acquire_user_connection_reservation(
ip_tracker: Arc<UserIpTracker>,
) -> Result<UserConnectionReservation> {
acquire_user_connection_reservation_for_incarnation(
user,
0,
config,
stats,
peer_addr,
ip_tracker,
user, 0, config, stats, peer_addr, ip_tracker,
)
.await
}
@@ -435,10 +425,7 @@ async fn acquire_user_connection_reservation_for_incarnation(
.or((config.access.user_max_tcp_conns_global_each > 0)
.then_some(config.access.user_max_tcp_conns_global_each))
.map(|value| value as u64);
let Some(connection_permit) = stats
.connection_authority()
.try_acquire(user, limit)
else {
let Some(connection_permit) = stats.connection_authority().try_acquire(user, limit) else {
return Err(ProxyError::ConnectionLimitExceeded {
user: user.to_string(),
});
+1 -4
View File
@@ -155,10 +155,7 @@ impl RunningClientHandler {
.or((config.access.user_max_tcp_conns_global_each > 0)
.then_some(config.access.user_max_tcp_conns_global_each))
.map(|v| v as u64);
let Some(_connection_permit) = stats
.connection_authority()
.try_acquire(user, limit)
else {
let Some(_connection_permit) = stats.connection_authority().try_acquire(user, limit) else {
return Err(ProxyError::ConnectionLimitExceeded {
user: user.to_string(),
});
+3 -6
View File
@@ -7,11 +7,11 @@ use tokio::sync::watch;
// Process controller and system-memory sampling remain outside data-plane accounting.
mod controller;
#[cfg(test)]
use controller::connection_fill_pct;
pub(crate) use controller::{
resolve_direct_buffer_hard_limit, run_direct_buffer_budget_controller,
};
#[cfg(test)]
use controller::connection_fill_pct;
/// Accounting granularity for process-wide Direct copy-buffer reservations.
pub(crate) const DIRECT_BUFFER_UNIT_BYTES: usize = 4 * 1024;
@@ -135,10 +135,7 @@ impl DirectBufferBudget {
.fetch_max(generation, Ordering::AcqRel);
}
fn begin_controller_update(
&self,
generation: u64,
) -> Option<ParkingMutexGuard<'_, ()>> {
fn begin_controller_update(&self, generation: u64) -> Option<ParkingMutexGuard<'_, ()>> {
let controller_update = self.controller_update.lock();
(self.active_controller_generation.load(Ordering::Acquire) == generation)
.then_some(controller_update)
+2 -5
View File
@@ -145,11 +145,8 @@ pub(super) fn connection_fill_pct(
return None;
}
let max_connections = max_connections as usize;
let active = max_connections.saturating_sub(
connection_slots
.available_permits()
.min(max_connections),
);
let active =
max_connections.saturating_sub(connection_slots.available_permits().min(max_connections));
Some((active.saturating_mul(100) / max_connections).min(100) as u8)
}
+2 -2
View File
@@ -74,8 +74,8 @@ pub(crate) use self::auth_probe::{
auth_probe_saturation_is_throttled_at_for_testing_in_shared,
auth_probe_saturation_is_throttled_for_testing_in_shared,
auth_probe_saturation_state_for_testing_in_shared,
auth_probe_saturation_state_lock_for_testing_in_shared, auth_probe_state_for_testing_in_shared,
auth_probe_slots_for_testing_in_shared, clear_auth_probe_state_for_testing_in_shared,
auth_probe_saturation_state_lock_for_testing_in_shared, auth_probe_slots_for_testing_in_shared,
auth_probe_state_for_testing_in_shared, clear_auth_probe_state_for_testing_in_shared,
clear_unknown_sni_warn_state_for_testing_in_shared, clear_warned_secrets_for_testing_in_shared,
insert_auth_probe_state_for_testing_in_shared,
should_emit_unknown_sni_warn_for_testing_in_shared, warned_secrets_for_testing_in_shared,
+8 -2
View File
@@ -403,7 +403,10 @@ mod bounded_registry_tests {
for index in (worker..ATTEMPTS).step_by(16) {
let octets = (index as u32).to_be_bytes();
let peer_ip = IpAddr::V4(std::net::Ipv4Addr::new(
octets[1], octets[2], octets[3], worker as u8,
octets[1],
octets[2],
octets[3],
worker as u8,
));
sticky_hint_record_success_in(
shared.as_ref(),
@@ -416,7 +419,10 @@ mod bounded_registry_tests {
}
});
assert_eq!(shared.handshake.sticky_user_by_ip.len(), STICKY_HINT_MAX_ENTRIES);
assert_eq!(
shared.handshake.sticky_user_by_ip.len(),
STICKY_HINT_MAX_ENTRIES
);
assert_eq!(
shared.handshake.sticky_user_by_ip_prefix.len(),
STICKY_HINT_MAX_ENTRIES
+1 -2
View File
@@ -397,8 +397,7 @@ fn auth_probe_record_failure_with_state_and_budget_in(
};
if state
.remove_if(&evict_key, |_, current| {
current.fail_streak == evict_fail_streak
&& current.last_seen == evict_last_seen
current.fail_streak == evict_fail_streak && current.last_seen == evict_last_seen
})
.is_some()
&& let Some(slots) = slots
+8 -2
View File
@@ -160,7 +160,10 @@ fn parallel_distinct_failures_respect_exact_auth_probe_capacity() {
for index in (worker..ATTEMPTS).step_by(16) {
let octets = (index as u32).to_be_bytes();
let peer_ip = IpAddr::V4(std::net::Ipv4Addr::new(
octets[1], octets[2], octets[3], worker as u8,
octets[1],
octets[2],
octets[3],
worker as u8,
));
auth_probe_record_failure_in(shared.as_ref(), peer_ip, Instant::now());
}
@@ -168,7 +171,10 @@ fn parallel_distinct_failures_respect_exact_auth_probe_capacity() {
}
});
assert_eq!(shared.handshake.auth_probe.len(), AUTH_PROBE_TRACK_MAX_ENTRIES);
assert_eq!(
shared.handshake.auth_probe.len(),
AUTH_PROBE_TRACK_MAX_ENTRIES
);
assert_eq!(
auth_probe_slots_for_testing_in_shared(shared.as_ref()),
AUTH_PROBE_TRACK_MAX_ENTRIES
+4 -4
View File
@@ -151,10 +151,10 @@ where
if let Some(snapshot) = config.runtime_user_auth() {
let sticky_ip_hint = sticky_hint_get_by_ip(shared, peer.ip());
let sticky_prefix_hint = sticky_hint_get_by_ip_prefix(shared, peer.ip());
let sticky_ip_candidates = sticky_ip_hint
.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
let sticky_prefix_candidates = sticky_prefix_hint
.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
let sticky_ip_candidates =
sticky_ip_hint.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
let sticky_prefix_candidates =
sticky_prefix_hint.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
let preferred_user_id = preferred_user.and_then(|user| snapshot.user_id_by_name(user));
let exact_user_id = exact_user.and_then(|user| snapshot.user_id_by_name(user));
let has_hint = sticky_ip_candidates.is_some_and(|ids| !ids.is_empty())
+1 -6
View File
@@ -400,12 +400,7 @@ where
.runtime_user_auth()
.and_then(|snapshot| snapshot.entry_by_id(user_id))
{
sticky_hint_record_success_in(
shared,
peer.ip(),
entry.hint_key,
client_sni.as_deref(),
);
sticky_hint_record_success_in(shared, peer.ip(), entry.hint_key, client_sni.as_deref());
record_recent_user_success_in(shared, entry.hint_key);
}
}
+6 -6
View File
@@ -40,17 +40,17 @@ pub(super) async fn validate_tls_client(
};
let sticky_ip_hint = sticky_hint_get_by_ip(shared, peer.ip());
let sticky_ip_candidates = sticky_ip_hint
.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
let sticky_ip_candidates =
sticky_ip_hint.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
let preferred_user_id = preferred_user_hint.and_then(|user| snapshot.user_id_by_name(user));
let sticky_sni_hint = client_sni
.as_deref()
.and_then(|sni| sticky_hint_get_by_sni(shared, sni));
let sticky_sni_candidates = sticky_sni_hint
.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
let sticky_sni_candidates =
sticky_sni_hint.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
let sticky_prefix_hint = sticky_hint_get_by_ip_prefix(shared, peer.ip());
let sticky_prefix_candidates = sticky_prefix_hint
.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
let sticky_prefix_candidates =
sticky_prefix_hint.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
let sni_candidates = client_sni
.as_deref()
.and_then(|sni| snapshot.sni_candidates(sni));
+6 -1
View File
@@ -191,7 +191,12 @@ where
if let (Some(limit), Some(quota_handle)) = (quota_limit, quota_handle) {
let soft_limit = quota_soft_cap(limit, quota_soft_overshoot_bytes);
match reserve_user_quota_with_yield(
quota_handle, data_len, soft_limit, stats, cancel, None,
quota_handle,
data_len,
soft_limit,
stats,
cancel,
None,
)
.await
{
+3 -3
View File
@@ -44,9 +44,9 @@ mod tests {
c2me_sender: AbortOnDropHandle::new(tokio::spawn(pending_child(DropSignal(
Arc::clone(&dropped),
)))),
me_writer: AbortOnDropHandle::new(tokio::spawn(pending_child(DropSignal(
Arc::clone(&dropped),
)))),
me_writer: AbortOnDropHandle::new(tokio::spawn(pending_child(DropSignal(Arc::clone(
&dropped,
))))),
flow_cancel: flow_cancel.clone(),
stop_tx: Some(stop_tx),
};
+1 -7
View File
@@ -414,13 +414,7 @@ impl<S: AsyncWrite + Unpin> AsyncWrite for StatsIo<S> {
if quota_reservation.is_none() {
this.stats.increment_quota_contention_timeout_total();
Self::arm_wait(&mut this.quota_wait, false, false);
if Self::poll_wait(
&mut this.quota_wait,
cx,
None,
RateDirection::Up,
)
.is_ready()
if Self::poll_wait(&mut this.quota_wait, cx, None, RateDirection::Up).is_ready()
{
cx.waker().wake_by_ref();
}
+7 -4
View File
@@ -219,8 +219,12 @@ impl ProxySharedState {
users: &HashMap<String, String>,
user_enabled: &HashMap<String, bool>,
) -> Option<Vec<(String, usize)>> {
self.user_admission
.activate_config_source(source_generation, expected_epoch, users, user_enabled)
self.user_admission.activate_config_source(
source_generation,
expected_epoch,
users,
user_enabled,
)
}
/// Applies an update only from the active runtime generation.
@@ -276,8 +280,7 @@ impl ProxySharedState {
user: &str,
credential_id: UserCredentialId,
) -> Option<UserAdmissionPublication<'_>> {
self.user_admission
.claim_authenticated(user, credential_id)
self.user_admission.claim_authenticated(user, credential_id)
}
pub(crate) fn register_user_session(
+2 -8
View File
@@ -310,10 +310,7 @@ async fn cancelled_ip_admission_releases_process_connection_permit() {
let user = "cancelled-admission-user";
let peer_addr: SocketAddr = "198.51.100.210:50000".parse().unwrap();
let mut config = ProxyConfig::default();
config
.access
.user_max_tcp_conns
.insert(user.to_string(), 1);
config.access.user_max_tcp_conns.insert(user.to_string(), 1);
let (entered_tx, entered_rx) = tokio::sync::oneshot::channel();
let (release_tx, release_rx) = tokio::sync::oneshot::channel();
@@ -370,10 +367,7 @@ async fn cancelled_async_release_preserves_ip_cleanup_ownership() {
let user = "cancelled-release-user";
let peer_addr: SocketAddr = "198.51.100.211:50001".parse().unwrap();
let mut config = ProxyConfig::default();
config
.access
.user_max_tcp_conns
.insert(user.to_string(), 1);
config.access.user_max_tcp_conns.insert(user.to_string(), 1);
let reservation = acquire_user_connection_reservation(
user,
@@ -77,9 +77,11 @@ fn controller_handoff_waits_for_inflight_update_and_fences_old_generation() {
activated_tx.send(()).unwrap();
});
assert!(activated_rx
.recv_timeout(Duration::from_millis(50))
.is_err());
assert!(
activated_rx
.recv_timeout(Duration::from_millis(50))
.is_err()
);
drop(update);
activated_rx.recv_timeout(Duration::from_secs(1)).unwrap();
activation.join().unwrap();
@@ -81,10 +81,8 @@ fn adversarial_intermediate_parent_swap_is_blocked_by_component_walk() {
let parent = directory.path().join("parent");
let moved = directory.path().join("moved");
let outside = directory.path().join("outside");
fs::create_dir_all(parent.join("nested"))
.expect("original nested directory must be creatable");
fs::create_dir_all(outside.join("nested"))
.expect("outside nested directory must be creatable");
fs::create_dir_all(parent.join("nested")).expect("original nested directory must be creatable");
fs::create_dir_all(outside.join("nested")).expect("outside nested directory must be creatable");
let candidate = parent.join("nested/unknown-dc.log");
let sanitized = sanitize_unknown_dc_log_path(
+1 -4
View File
@@ -154,10 +154,7 @@ enum BucketReserveError {
impl BucketReserveError {
fn exhausted_reserve_budget(self) -> bool {
matches!(
self,
Self::Contended | Self::ReserveAndRefundContended
)
matches!(self, Self::Contended | Self::ReserveAndRefundContended)
}
}
+12 -25
View File
@@ -67,12 +67,8 @@ impl DirectionBucket {
if self.should_force_reserve_failure() {
return Err(current);
}
self.state.compare_exchange(
current,
next,
Ordering::Relaxed,
Ordering::Relaxed,
)
self.state
.compare_exchange(current, next, Ordering::Relaxed, Ordering::Relaxed)
}
#[inline(always)]
@@ -81,12 +77,8 @@ impl DirectionBucket {
if self.should_force_refund_failure() {
return Err(current);
}
self.state.compare_exchange(
current,
next,
Ordering::Relaxed,
Ordering::Relaxed,
)
self.state
.compare_exchange(current, next, Ordering::Relaxed, Ordering::Relaxed)
}
fn unpack(state: u64) -> (u64, u64) {
@@ -355,9 +347,9 @@ impl CidrDirectionBucket {
});
};
let user_granted = user_debit.granted();
let Some(aggregate_debit) = self
.used
.try_reserve_at(epoch, cap_epoch, user_granted, budget)?
let Some(aggregate_debit) =
self.used
.try_reserve_at(epoch, cap_epoch, user_granted, budget)?
else {
return Ok(CidrReservation {
granted: 0,
@@ -410,12 +402,8 @@ impl CidrUserDirectionState {
if observed_epoch > epoch {
return Err(BucketReserveError::StaleEpoch);
}
let Some(mut active_debit) = active_users.try_reserve_at(
epoch,
PACKED_USAGE_MASK,
1,
budget,
)?
let Some(mut active_debit) =
active_users.try_reserve_at(epoch, PACKED_USAGE_MASK, 1, budget)?
else {
return Ok(false);
};
@@ -532,10 +520,9 @@ impl CidrBucket {
}
let cap_epoch = bytes_per_epoch(cap_bps);
match direction {
RateDirection::Up => {
self.up
.try_reserve(&share.up, epoch, cap_epoch, requested, budget)
}
RateDirection::Up => self
.up
.try_reserve(&share.up, epoch, cap_epoch, requested, budget),
RateDirection::Down => {
self.down
.try_reserve(&share.down, epoch, cap_epoch, requested, budget)
+25 -28
View File
@@ -61,32 +61,28 @@ impl TrafficLease {
let mut granted = requested;
let mut user_debit = None;
if let Some(user_bucket) = binding.user_bucket.as_ref() {
let user_reservation = match user_bucket.try_reserve(
direction,
epoch,
granted,
&mut budget,
) {
Ok(reservation) => reservation,
Err(error) => {
if error.exhausted_reserve_budget() {
self.limiter
.user_scope
.reserve_cas_retry_exhausted(direction);
let user_reservation =
match user_bucket.try_reserve(direction, epoch, granted, &mut budget) {
Ok(reservation) => reservation,
Err(error) => {
if error.exhausted_reserve_budget() {
self.limiter
.user_scope
.reserve_cas_retry_exhausted(direction);
}
return TrafficReservation {
result: TrafficConsumeResult {
granted: 0,
blocked_user: false,
blocked_cidr: false,
},
_binding: binding,
user: None,
cidr: None,
cidr_user: None,
};
}
return TrafficReservation {
result: TrafficConsumeResult {
granted: 0,
blocked_user: false,
blocked_cidr: false,
},
_binding: binding,
user: None,
cidr: None,
cidr_user: None,
};
}
};
};
user_debit = user_reservation.debit;
if user_reservation.granted == 0 {
self.limiter.observe_throttle(direction, true, false);
@@ -107,9 +103,10 @@ impl TrafficLease {
let mut cidr_debit = None;
let mut cidr_user_debit = None;
if let (Some(cidr_bucket), Some(cidr_user_share)) =
(binding.cidr_bucket.as_ref(), binding.cidr_user_share.as_ref())
{
if let (Some(cidr_bucket), Some(cidr_user_share)) = (
binding.cidr_bucket.as_ref(),
binding.cidr_user_share.as_ref(),
) {
let cidr_reservation = match cidr_bucket.try_reserve_for_user(
direction,
cidr_user_share,
+32 -8
View File
@@ -330,14 +330,38 @@ impl TrafficLimiter {
cidr_refund_down,
] = values;
for (counter, value) in [
(&self.user_scope.contention_up.reserve_exhausted_total, user_reserve_up),
(&self.user_scope.contention_down.reserve_exhausted_total, user_reserve_down),
(&self.user_scope.contention_up.refund_exhausted_total, user_refund_up),
(&self.user_scope.contention_down.refund_exhausted_total, user_refund_down),
(&self.cidr_scope.contention_up.reserve_exhausted_total, cidr_reserve_up),
(&self.cidr_scope.contention_down.reserve_exhausted_total, cidr_reserve_down),
(&self.cidr_scope.contention_up.refund_exhausted_total, cidr_refund_up),
(&self.cidr_scope.contention_down.refund_exhausted_total, cidr_refund_down),
(
&self.user_scope.contention_up.reserve_exhausted_total,
user_reserve_up,
),
(
&self.user_scope.contention_down.reserve_exhausted_total,
user_reserve_down,
),
(
&self.user_scope.contention_up.refund_exhausted_total,
user_refund_up,
),
(
&self.user_scope.contention_down.refund_exhausted_total,
user_refund_down,
),
(
&self.cidr_scope.contention_up.reserve_exhausted_total,
cidr_reserve_up,
),
(
&self.cidr_scope.contention_down.reserve_exhausted_total,
cidr_reserve_down,
),
(
&self.cidr_scope.contention_up.refund_exhausted_total,
cidr_refund_up,
),
(
&self.cidr_scope.contention_down.refund_exhausted_total,
cidr_refund_down,
),
] {
counter.store(value, Ordering::Relaxed);
}
+2 -11
View File
@@ -65,12 +65,7 @@ fn reserve_at(
cap: u64,
requested: u64,
) -> Result<Option<DirectionDebit>, BucketReserveError> {
bucket.try_reserve_at(
epoch,
cap,
requested,
&mut ReserveCasBudget::new(),
)
bucket.try_reserve_at(epoch, cap, requested, &mut ReserveCasBudget::new())
}
#[test]
@@ -346,11 +341,7 @@ fn concurrent_first_use_counts_one_active_cidr_user() {
let barrier = Arc::clone(&barrier);
threads.push(std::thread::spawn(move || {
barrier.wait();
user.ensure_active(
13,
&bucket.active_users,
&mut ReserveCasBudget::new(),
)
user.ensure_active(13, &bucket.active_users, &mut ReserveCasBudget::new())
}));
}
let results: Vec<_> = threads
@@ -9,10 +9,7 @@ fn reserve_stops_after_the_attempt_limit() {
let reservation = bucket.try_reserve_at(1, 100, 1, &mut budget);
assert!(matches!(
reservation,
Err(BucketReserveError::Contended)
));
assert!(matches!(reservation, Err(BucketReserveError::Contended)));
assert_eq!(
bucket.reserve_cas_attempts(),
RESERVE_CAS_ATTEMPT_LIMIT as u64
@@ -32,7 +29,10 @@ fn reserve_succeeds_on_the_last_allowed_attempt() {
.unwrap();
assert_eq!(debit.commit_all(), 80);
assert_eq!(bucket.reserve_cas_attempts(), RESERVE_CAS_ATTEMPT_LIMIT as u64);
assert_eq!(
bucket.reserve_cas_attempts(),
RESERVE_CAS_ATTEMPT_LIMIT as u64
);
assert!(budget.is_exhausted());
assert_eq!(bucket.used_at(1), Some(80));
}
@@ -121,15 +121,7 @@ fn lease_contention_is_not_reported_as_throttling() {
let lease = limiter
.acquire_lease("alice", "203.0.113.7".parse().unwrap())
.unwrap();
let bucket = Arc::clone(
&lease
.binding
.load_full()
.user_bucket
.as_ref()
.unwrap()
.down,
);
let bucket = Arc::clone(&lease.binding.load_full().user_bucket.as_ref().unwrap().down);
bucket.force_reserve_failures(RESERVE_CAS_ATTEMPT_LIMIT);
let result = lease.try_consume(RateDirection::Down, 1);
@@ -187,12 +179,7 @@ fn cidr_contention_rolls_back_provisional_user_debits() {
assert!(!result.blocked_user);
assert!(!result.blocked_cidr);
assert_eq!(
binding
.user_bucket
.as_ref()
.unwrap()
.down
.used_at(epoch),
binding.user_bucket.as_ref().unwrap().down.used_at(epoch),
Some(0)
);
assert_eq!(cidr_bucket.down.used.used_at(epoch), None);
@@ -275,8 +262,7 @@ fn contention_snapshot_preserves_scope_direction_and_operation() {
fn cidr_activation_consumes_one_shared_attempt_budget() {
let bucket = CidrDirectionBucket::default();
let user = CidrUserDirectionState::default();
user.used
.force_reserve_failures(RESERVE_CAS_ATTEMPT_LIMIT);
user.used.force_reserve_failures(RESERVE_CAS_ATTEMPT_LIMIT);
let mut budget = ReserveCasBudget::new();
let activation = user.ensure_active(13, &bucket.active_users, &mut budget);
@@ -360,19 +346,11 @@ fn cidr_first_grants_preserve_the_current_soft_fair_share() {
let first = CidrUserDirectionState::default();
let second = CidrUserDirectionState::default();
assert_eq!(
first.ensure_active(
17,
&bucket.active_users,
&mut ReserveCasBudget::new(),
),
first.ensure_active(17, &bucket.active_users, &mut ReserveCasBudget::new(),),
Ok(true)
);
assert_eq!(
second.ensure_active(
17,
&bucket.active_users,
&mut ReserveCasBudget::new(),
),
second.ensure_active(17, &bucket.active_users, &mut ReserveCasBudget::new(),),
Ok(true)
);
@@ -391,21 +369,13 @@ fn cidr_first_grants_preserve_the_current_soft_fair_share() {
.as_mut()
.unwrap()
.commit_all();
first_reservation
.user_debit
.as_mut()
.unwrap()
.commit_all();
first_reservation.user_debit.as_mut().unwrap().commit_all();
second_reservation
.aggregate_debit
.as_mut()
.unwrap()
.commit_all();
second_reservation
.user_debit
.as_mut()
.unwrap()
.commit_all();
second_reservation.user_debit.as_mut().unwrap().commit_all();
assert_eq!(bucket.used.used_at(17), Some(100));
assert_eq!(first.used.used_at(17), Some(50));
assert_eq!(second.used.used_at(17), Some(50));
+5 -10
View File
@@ -335,8 +335,7 @@ impl UserAdmissionAuthority {
record.incarnation = incarnation;
if identity_changed {
if previous.is_some() {
self.quota_store
.advance_preserving_usage(user, incarnation);
self.quota_store.advance_preserving_usage(user, incarnation);
} else {
self.quota_store.activate_fresh(user, incarnation);
}
@@ -420,7 +419,8 @@ impl UserAdmissionAuthority {
}
let record = state.users.get(user)?;
let effective = record.effective()?;
(effective.enabled && effective.credential_id == credential_id).then_some(record.incarnation)
(effective.enabled && effective.credential_id == credential_id)
.then_some(record.incarnation)
}
/// Starts a short publication critical section for one authenticated owner.
@@ -456,10 +456,7 @@ impl UserAdmissionAuthority {
}
/// Registers a legacy owner when no credential snapshot is available.
pub(crate) fn register_legacy(
self: &Arc<Self>,
user: &str,
) -> Option<UserSessionRegistration> {
pub(crate) fn register_legacy(self: &Arc<Self>, user: &str) -> Option<UserSessionRegistration> {
let credential_id = {
let state = self.state.lock();
if !state.initialized {
@@ -520,9 +517,7 @@ pub(crate) fn credential_id_from_hex(secret: &str) -> Option<UserCredentialId> {
Some(credential_id(&secret))
}
fn cancel_owners(
cancellations: Vec<(String, Vec<CancellationToken>)>,
) -> Vec<(String, usize)> {
fn cancel_owners(cancellations: Vec<(String, Vec<CancellationToken>)>) -> Vec<(String, usize)> {
cancellations
.into_iter()
.map(|(user, tokens)| {
+3 -12
View File
@@ -51,12 +51,7 @@ fn stale_candidate_cannot_overwrite_newer_mutation() {
assert!(
authority
.activate_config_source(
2,
Some(candidate_epoch),
&users(secret),
&HashMap::new(),
)
.activate_config_source(2, Some(candidate_epoch), &users(secret), &HashMap::new(),)
.is_none()
);
assert!(!authority.is_user_enabled("alice"));
@@ -105,9 +100,7 @@ fn registration_dropped_before_publication_cannot_leave_an_owner() {
let secret = "00112233445566778899aabbccddeeff";
authority.apply_config(&users(secret), &HashMap::new());
let credential = credential_id_from_hex(secret).unwrap();
let mut publication = authority
.claim_authenticated("alice", credential)
.unwrap();
let mut publication = authority.claim_authenticated("alice", credential).unwrap();
let registration = publication.take_registration().unwrap();
drop(registration);
@@ -126,9 +119,7 @@ fn quota_identity_follows_credential_rotation_and_recreation() {
let old_incarnation = authority
.authenticated_incarnation("alice", credential_id_from_hex(old_secret).unwrap())
.unwrap();
let old_quota = quota_store
.handle_exact("alice", old_incarnation)
.unwrap();
let old_quota = quota_store.handle_exact("alice", old_incarnation).unwrap();
old_quota.charge(40);
let rotated = authority.stage_user("alice", new_secret, true).unwrap();