Skip to content

Commit b0b2e08

Browse files
committed
Operate sensibly if the timing of requests isn't monotonic
1 parent 6e74ce8 commit b0b2e08

File tree

1 file changed

+31
-3
lines changed

1 file changed

+31
-3
lines changed

src/stats/mod.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,23 @@ impl<W: Write + Send + 'static> AggregatedStats<W> {
9090
fn maybe_update_counter<'a>(&'a self, now: DateTime<Utc>, guard: &'a impl Guard) -> &'a Counts {
9191
let now = mk_num(now);
9292

93-
let prev_day = self.today.swap(now, Ordering::Relaxed);
93+
let mut prev_day = self.today.load(Ordering::Relaxed);
94+
95+
// If our "now" time is in the past (perhaps tasks got out of order or something), we want to count this redirect towards the most recent day rather than getting rid of the newest day and replacing it with data intended for the oldest day.
96+
97+
while prev_day < now {
98+
match self
99+
.today
100+
.compare_exchange(prev_day, now, Ordering::Relaxed, Ordering::Relaxed)
101+
{
102+
Ok(_) => break,
103+
Err(new_prev_day) => {
104+
prev_day = new_prev_day;
105+
}
106+
}
107+
}
94108

95-
if prev_day != now {
109+
if prev_day < now {
96110
let new_counter: *mut Counts = Box::into_raw(Box::new(HashMap::new()));
97111

98112
// We need this guard to go into our task so it needs to be owned
@@ -353,10 +367,24 @@ mod tests {
353367
"},
354368
)
355369
.await;
370+
stats.redirected_impl(a("0.0.0.0"), i("b.com"), i("c.com"), t(4));
356371
stats.redirected_impl(a("0.0.0.0"), i("c.com"), i("a.com"), t(2) + day);
357372

358373
assert_eq!(stats.aggregated.counter(&guard).len(), 2);
359-
stats.assert_stat_entry(("b.com", "c.com", "b.com"), 1);
374+
stats.assert_stat_entry(("b.com", "c.com", "b.com"), 2);
375+
stats.assert_stat_entry(("c.com", "a.com", "b.com"), 1);
376+
377+
stats.redirected_impl(a("0.0.0.0"), i("c.com"), i("a.com"), t(2) + day + day);
378+
assert_same_data(
379+
&mut rx,
380+
indoc! {"
381+
1,b.com,c.com,b.com,2
382+
1,c.com,a.com,b.com,1
383+
"},
384+
)
385+
.await;
386+
387+
assert_eq!(stats.aggregated.counter(&guard).len(), 1);
360388
stats.assert_stat_entry(("c.com", "a.com", "b.com"), 1);
361389
}
362390
}

0 commit comments

Comments
 (0)