This commit is contained in:
Mateusz Gruszczyński committed 2026-10-06 11:29:34 +02:00
1 parent cf25423dde
commit 52cc137c73
50 files changed
+410 -172

No files matched your search

+35 -5
View File
@@ -103,6 +103,11 @@ impl ProxyClient {
pub fn rotation_stats(&self) -> ClientRotationStats {
self.inner.stats()
}
/// Recycle an aged connection pool even when no user request arrives.
pub(crate) fn maintain_rotation(&self) {
self.inner.maintain_rotation();
}
}
impl RotatingClient {
@@ -136,12 +141,36 @@ impl RotatingClient {
.pool_recycle_seconds
.saturating_mul(1_000);
if request_due || age_due {
self.rotate(observed_generation, if request_due { "requests" } else { "age" });
self.rotate(
observed_generation,
if request_due { "requests" } else { "age" },
true,
);
}
self.current.load_full()
}
fn rotate(&self, observed_generation: u64, reason: &'static str) {
fn maintain_rotation(&self) {
self.maintain_rotation_at(monotonic_millis());
}
fn maintain_rotation_at(&self, now_ms: u64) {
let recycle_seconds = self.factory.keepalive.pool_recycle_seconds;
if recycle_seconds == 0 {
return;
}
let age_ms = now_ms.saturating_sub(self.generation_started_ms.load(Ordering::Relaxed));
if age_ms >= recycle_seconds.saturating_mul(1_000) {
self.rotate(self.generation.load(Ordering::Acquire), "age", false);
}
}
fn rotate(
&self,
observed_generation: u64,
reason: &'static str,
triggering_request: bool,
) {
if self.generation.load(Ordering::Acquire) != observed_generation
|| self
.rotating
@@ -159,9 +188,10 @@ impl RotatingClient {
Ok(client) => {
let next_generation = observed_generation.saturating_add(1);
self.current.store(Arc::new(client));
// The request that triggered the swap is sent through the new
// generation after rotate() returns, so count it there.
self.generation_requests.store(1, Ordering::Relaxed);
// Request-driven rotation sends the triggering request through
// the new generation. Maintenance-driven rotation happens idle.
self.generation_requests
.store(if triggering_request { 1 } else { 0 }, Ordering::Relaxed);
self.generation_started_ms
.store(monotonic_millis(), Ordering::Relaxed);
self.generation.store(next_generation, Ordering::Release);