proxywatchd: add sanity checks to rate/peak calculations
This commit is contained in:
@@ -410,18 +410,29 @@ class Stats():
|
|||||||
with self.lock:
|
with self.lock:
|
||||||
elapsed = now - self.last_history_time
|
elapsed = now - self.last_history_time
|
||||||
if elapsed >= 5: # Update every 5 seconds
|
if elapsed >= 5: # Update every 5 seconds
|
||||||
# Rate
|
# Rate - with sanity checks
|
||||||
tests_delta = self.tested - self.last_history_tested
|
tests_delta = self.tested - self.last_history_tested
|
||||||
|
if tests_delta < 0:
|
||||||
|
# Counter wrapped or corrupted - reset baseline
|
||||||
|
self.last_history_tested = self.tested
|
||||||
|
tests_delta = 0
|
||||||
rate = tests_delta / elapsed if elapsed > 0 else 0
|
rate = tests_delta / elapsed if elapsed > 0 else 0
|
||||||
|
# Cap at reasonable max (100/s is generous for proxy testing)
|
||||||
|
if rate > 100:
|
||||||
|
rate = 0 # Discard bogus value
|
||||||
self.rate_history.append(round(rate, 2))
|
self.rate_history.append(round(rate, 2))
|
||||||
if len(self.rate_history) > self.HISTORY_SIZE:
|
if len(self.rate_history) > self.HISTORY_SIZE:
|
||||||
self.rate_history.pop(0)
|
self.rate_history.pop(0)
|
||||||
if rate > self.peak_rate:
|
if rate > self.peak_rate and rate <= 100:
|
||||||
self.peak_rate = rate
|
self.peak_rate = rate
|
||||||
|
|
||||||
# Success rate
|
# Success rate - with sanity checks
|
||||||
passed_delta = self.passed - self.last_history_passed
|
passed_delta = self.passed - self.last_history_passed
|
||||||
|
if passed_delta < 0:
|
||||||
|
self.last_history_passed = self.passed
|
||||||
|
passed_delta = 0
|
||||||
sr = (passed_delta / tests_delta * 100) if tests_delta > 0 else 0
|
sr = (passed_delta / tests_delta * 100) if tests_delta > 0 else 0
|
||||||
|
sr = min(sr, 100.0) # Cap at 100%
|
||||||
self.success_rate_history.append(round(sr, 1))
|
self.success_rate_history.append(round(sr, 1))
|
||||||
if len(self.success_rate_history) > self.HISTORY_SIZE:
|
if len(self.success_rate_history) > self.HISTORY_SIZE:
|
||||||
self.success_rate_history.pop(0)
|
self.success_rate_history.pop(0)
|
||||||
@@ -576,7 +587,9 @@ class Stats():
|
|||||||
self.proto_passed['socks4'] = state.get('proto_socks4_passed', 0)
|
self.proto_passed['socks4'] = state.get('proto_socks4_passed', 0)
|
||||||
self.proto_tested['socks5'] = state.get('proto_socks5_tested', 0)
|
self.proto_tested['socks5'] = state.get('proto_socks5_tested', 0)
|
||||||
self.proto_passed['socks5'] = state.get('proto_socks5_passed', 0)
|
self.proto_passed['socks5'] = state.get('proto_socks5_passed', 0)
|
||||||
self.peak_rate = state.get('peak_rate', 0.0)
|
# Cap peak_rate at reasonable maximum (corrupted values from bugs)
|
||||||
|
raw_peak = state.get('peak_rate', 0.0)
|
||||||
|
self.peak_rate = min(raw_peak, 100.0) # Max 100/s is generous
|
||||||
# Note: start_time is NOT restored - uptime reflects current session
|
# Note: start_time is NOT restored - uptime reflects current session
|
||||||
# Restore failure categories
|
# Restore failure categories
|
||||||
if state.get('fail_categories'):
|
if state.get('fail_categories'):
|
||||||
|
|||||||
Reference in New Issue
Block a user