Merge pull request #554 from ashishpatel26/fix/481-dashboard-hero-tile-multi-worker-savings

fix(dashboard): stable 'Proxy $ Saved' hero tile under --workers > 1 (#481)
This commit is contained in:
JD Davis 2026-06-08 18:11:26 -05:00 committed by GitHub
commit fd73b88368
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 45 additions and 8 deletions

View file

@ -105,12 +105,12 @@
<div class="bg-surface rounded-lg p-4 border border-border">
<div class="text-xs text-gray-500 uppercase tracking-wide mb-1">Proxy $ Saved</div>
<div class="flex items-baseline gap-2">
<span class="text-3xl font-light tabular-nums text-emerald-400" x-text="'$' + formatCurrency(stats.cost?.savings_usd || 0)"></span>
<span class="text-3xl font-light tabular-nums text-emerald-400" x-text="'$' + formatCurrency(stats.persistent_savings?.lifetime?.compression_savings_usd || 0)"></span>
</div>
<div class="mt-2 text-xs text-gray-500">
<span x-show="stats.cost?.savings_usd > 0"
<span x-show="(stats.persistent_savings?.lifetime?.compression_savings_usd || 0) > 0"
x-text="formatNumber(stats.tokens?.proxy_compression_saved || 0) + ' proxy tokens only; ' + cliFilteringLabel + ' excluded from $'"></span>
<span x-show="!(stats.cost?.savings_usd > 0)"
<span x-show="!((stats.persistent_savings?.lifetime?.compression_savings_usd || 0) > 0)"
x-text="formatNumber(stats.requests?.total || 0) + ' requests processed'"></span>
</div>
</div>

View file

@ -3099,12 +3099,13 @@ def run_server(
# sticky-session workaround.
logger.warning(
"Headroom is running with workers=%d. The in-memory CCR store, "
"compression cache, prefix tracker, and TOIN state are all "
"compression cache, prefix tracker, TOIN state, and CostTracker are all "
"per-process; multi-worker deployments produce silent retrieval "
"failures and avoidable cache busts when sessions land on different "
"workers. Run --workers 1 (or place a sticky-session load balancer "
"in front of multiple --workers 1 processes). See RUST_DEV.md → "
"'Multi-worker deployment — CCR fragmentation'.",
"failures, avoidable cache busts, and an unstable dashboard 'Proxy $ Saved' "
"hero tile (each /stats poll hits a different worker's partial total) when "
"sessions land on different workers. Run --workers 1 (or place a "
"sticky-session load balancer in front of multiple --workers 1 processes). "
"See RUST_DEV.md → 'Multi-worker deployment — CCR fragmentation'.",
workers,
)
os.environ[_MULTI_WORKER_CONFIG_ENV] = json.dumps(_proxy_config_payload(config))

View file

@ -211,6 +211,42 @@ def test_record_compression_savings_skips_empty_updates_and_normalizes_timestamp
assert persisted["history"][-1]["timestamp"] == "2026-03-27T12:34:00Z"
def test_savings_tracker_save_does_not_flock_target_inode_before_replace(tmp_path, monkeypatch):
path = tmp_path / "proxy_savings.json"
tracker = SavingsTracker(path=str(path))
tracker.record_request(
model="gpt-4o",
input_tokens=120,
tokens_saved=10,
timestamp="2026-03-27T09:00:00Z",
)
assert path.exists()
flock_calls: list[int] = []
class _FcntlSpy:
LOCK_EX = 1
LOCK_UN = 2
def flock(self, _fh, operation: int) -> None:
flock_calls.append(operation)
monkeypatch.setattr(savings_tracker_module, "_HAS_FCNTL", True, raising=False)
monkeypatch.setattr(savings_tracker_module, "_fcntl", _FcntlSpy(), raising=False)
tracker.record_request(
model="gpt-4o",
input_tokens=80,
tokens_saved=5,
timestamp="2026-03-27T09:10:00Z",
)
assert flock_calls == []
persisted = json.loads(path.read_text(encoding="utf-8"))
assert persisted["lifetime"]["tokens_saved"] == 15
def test_litellm_resolution_and_savings_estimation_fallbacks(monkeypatch):
def fake_cost_per_token(*, model, prompt_tokens, completion_tokens):
if model in {"gpt-4o", "anthropic/claude-sonnet-4-6"}: