feat: finalize smart pool tracking with hysteresis (handle jumps, drops, and expiry)
This commit is contained in:
+43
-19
@@ -999,39 +999,63 @@ def active_monitor_loop():
|
|||||||
dynamic_key = f"limit:dynamic:volcengine:remaining:{target}"
|
dynamic_key = f"limit:dynamic:volcengine:remaining:{target}"
|
||||||
|
|
||||||
# ==========================================
|
# ==========================================
|
||||||
# 🏔️ Peak Tracking & Stable Limit
|
# 🏔️ Smart Peak Tracking (Auto-Correction)
|
||||||
# ==========================================
|
# ==========================================
|
||||||
# Logic Change: Track "Total Daily Budget" instead of just "Remaining".
|
# Strategy:
|
||||||
# Total Budget = Current Usage + Current Remaining.
|
# 1. Capture Jumps (Recovery): If Balance jumps UP, trust it immediately. (Fixes latency)
|
||||||
# This handles mid-day restarts correctly.
|
# 2. Capture Drops (Expiry): If Balance drops HUGE (>20%), trust it. (Fixes expiry)
|
||||||
|
# - Why trust drops? Because if it's a false drop (glitch), Step 1 will fix it
|
||||||
|
# automatically on the next sync when it "Jumps" back up.
|
||||||
|
|
||||||
total_pool = current_usage + balance
|
total_pool = current_usage + balance
|
||||||
|
|
||||||
peak_key = f"volc:peak_pool:{today_str}:{target}"
|
peak_key = f"volc:peak_pool:{today_str}:{target}"
|
||||||
current_peak = float(redis_client.get(peak_key) or 0)
|
|
||||||
|
|
||||||
if total_pool > current_peak:
|
# Short-term memory (Last seen value)
|
||||||
|
last_pool_key = f"volc:last_seen_pool:{target}"
|
||||||
|
last_pool_val = redis_client.get(last_pool_key)
|
||||||
|
last_pool = float(last_pool_val) if last_pool_val else 0.0
|
||||||
|
|
||||||
|
# Long-term memory (Day's High Water Mark)
|
||||||
|
old_peak_val = redis_client.get(peak_key)
|
||||||
|
historical_peak = float(old_peak_val) if old_peak_val else 0.0
|
||||||
|
|
||||||
|
current_peak = historical_peak
|
||||||
|
|
||||||
|
# 1. JUMP DETECTION (Recharge / Latency Resolved)
|
||||||
|
# If pool jumps significantly (>5%) from last seen, it's a fresh, true value.
|
||||||
|
if total_pool > (last_pool * 1.05) and last_pool > 0:
|
||||||
if DEBUG_MODE:
|
if DEBUG_MODE:
|
||||||
print(
|
print(
|
||||||
f"DEBUG: New Peak Pool for {target}: {int(total_pool):,} (Usg:{int(current_usage):,} + Rem:{int(balance):,})",
|
f"DEBUG: 📈 Balance Jump ({int(last_pool):,} -> {int(total_pool):,}) - Locking New Peak.",
|
||||||
flush=True,
|
flush=True,
|
||||||
)
|
)
|
||||||
redis_client.setex(
|
|
||||||
peak_key, 172800, int(total_pool)
|
|
||||||
) # 48h retention
|
|
||||||
current_peak = total_pool
|
current_peak = total_pool
|
||||||
|
redis_client.setex(peak_key, 172800, int(current_peak))
|
||||||
|
|
||||||
# Fallback: If peak is somehow less than balance (shouldn't happen with logic above), fix it
|
# 2. DROP DETECTION (Resource Expiry)
|
||||||
if current_peak < balance:
|
# If pool drops MASSIVELY (>20%) below historical peak, it's likely an expiry.
|
||||||
current_peak = balance
|
# We accept this drop. If it was just a glitch, Rule #1 will fix it next time it bounces back.
|
||||||
|
elif (
|
||||||
|
total_pool < (historical_peak * 0.8) and historical_peak > 0
|
||||||
|
):
|
||||||
|
if DEBUG_MODE:
|
||||||
|
print(
|
||||||
|
f"DEBUG: 📉 Expiry/Drop Detected ({int(historical_peak):,} -> {int(total_pool):,}) - Adjusting Limit Down.",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
current_peak = total_pool
|
||||||
|
redis_client.setex(peak_key, 172800, int(current_peak))
|
||||||
|
|
||||||
|
# 3. INITIALIZATION / DRIFT
|
||||||
|
elif historical_peak == 0 or total_pool > historical_peak:
|
||||||
|
current_peak = total_pool
|
||||||
|
redis_client.setex(peak_key, 172800, int(current_peak))
|
||||||
|
|
||||||
|
# Always update "Last Seen" for next comparison
|
||||||
|
redis_client.setex(last_pool_key, 86400, int(total_pool))
|
||||||
|
|
||||||
# Calculate Stable Limit
|
# Calculate Stable Limit
|
||||||
# Limit = Peak Pool - Buffer
|
|
||||||
# Buffer = Max(Peak * 15%, 250,000)
|
|
||||||
safety_margin = max(current_peak * 0.15, 250000)
|
safety_margin = max(current_peak * 0.15, 250000)
|
||||||
|
|
||||||
# The Limit is the "Max Allowed Cumulative Usage"
|
|
||||||
# Max Usage = Total Pool - Buffer
|
|
||||||
stable_limit = int(max(0, current_peak - safety_margin))
|
stable_limit = int(max(0, current_peak - safety_margin))
|
||||||
|
|
||||||
stable_limit_key = (
|
stable_limit_key = (
|
||||||
|
|||||||
Reference in New Issue
Block a user