Track observed node throughput
This commit is contained in:
@@ -262,6 +262,11 @@ def test_proxy_chat_bills_client_and_credits_node(billed_tracker):
|
||||
assert summary["node_pending"]["wallet-head"] == pytest.approx(0.02 * 0.90)
|
||||
assert summary["protocol_cut"] == pytest.approx(0.02 * 0.10)
|
||||
|
||||
stats = json.loads(urllib.request.urlopen(f"{tracker_url}/v1/stats").read())
|
||||
node_stats = next(iter(stats["nodes"].values()))["models"][MODEL]
|
||||
assert node_stats["tokens_per_sec_last_hour"] is not None
|
||||
assert node_stats["sample_count_last_hour"] == 1
|
||||
|
||||
|
||||
def test_proxy_chat_402_when_balance_exhausted(billed_tracker):
|
||||
tracker_url, ledger = billed_tracker
|
||||
|
||||
@@ -10,7 +10,7 @@ from meshnet_tracker.server import TrackerServer
|
||||
PANELS = [
|
||||
"Tracker hive", "Nodes & coverage", "Client balances",
|
||||
"Node pending payouts", "Settlement history",
|
||||
"Strikes / bans / forfeitures", "Model usage",
|
||||
"Strikes / bans / forfeitures", "Model usage", "Node throughput",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import time
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
import pytest
|
||||
|
||||
from meshnet_gateway.server import GatewayServer, _banned_route_wallet
|
||||
from meshnet_node.server import StubNodeServer
|
||||
from meshnet_contracts import LocalSolanaContracts
|
||||
@@ -1501,6 +1503,24 @@ def test_stats_collector_records_and_returns_rpms():
|
||||
assert combined["my-model"]["rpm_last_month"] > 0
|
||||
|
||||
|
||||
def test_stats_collector_records_node_model_tokens_per_second():
|
||||
from meshnet_tracker.server import _StatsCollector
|
||||
|
||||
collector = _StatsCollector()
|
||||
now = 1_000_000.0
|
||||
collector.record_node_throughput("node-a", "my-model", total_tokens=200, elapsed_seconds=2.0, now=now)
|
||||
collector.record_node_throughput("node-a", "my-model", total_tokens=300, elapsed_seconds=3.0, now=now)
|
||||
|
||||
node_stats = collector.get_node_model_stats("node-a", "my-model", now=now)
|
||||
assert node_stats["tokens_per_sec_last_hour"] == pytest.approx(100.0)
|
||||
assert node_stats["tokens_per_sec_last_day"] == pytest.approx(100.0)
|
||||
assert node_stats["tokens_per_sec_last_month"] == pytest.approx(100.0)
|
||||
assert node_stats["sample_count_last_hour"] == 2
|
||||
|
||||
node_models = collector.get_node_throughput_stats(now=now)
|
||||
assert node_models["node-a"]["models"]["my-model"]["tokens_per_sec_last_hour"] == pytest.approx(100.0)
|
||||
|
||||
|
||||
def test_stats_collector_merges_peer_rpms_additively():
|
||||
from meshnet_tracker.server import _StatsCollector
|
||||
|
||||
@@ -1526,12 +1546,15 @@ def test_stats_sqlite_persistence_survives_restart(tmp_path):
|
||||
collector = _StatsCollector(db_path=db)
|
||||
for _ in range(10):
|
||||
collector.record_request("persistent-model", now=now)
|
||||
collector.record_node_throughput("node-p", "persistent-model", total_tokens=120, elapsed_seconds=2.0, now=now)
|
||||
collector.save_to_db()
|
||||
|
||||
collector2 = _StatsCollector(db_path=db)
|
||||
combined = collector2.get_combined_stats(now=now)
|
||||
assert "persistent-model" in combined
|
||||
assert combined["persistent-model"]["rpm_last_hour"] > 0
|
||||
node_models = collector2.get_node_throughput_stats(now=now)
|
||||
assert node_models["node-p"]["models"]["persistent-model"]["tokens_per_sec_last_hour"] == pytest.approx(60.0)
|
||||
|
||||
|
||||
def test_stats_gossip_endpoint_merges_peer_slice():
|
||||
@@ -1622,6 +1645,20 @@ def test_select_route_prefers_higher_throughput_node_when_shards_equal():
|
||||
assert route[0].node_id == "fast"
|
||||
|
||||
|
||||
def test_select_route_prefers_observed_model_throughput_over_startup_benchmark():
|
||||
"""Observed per-model TPS is the primary routing signal once available."""
|
||||
from meshnet_tracker.server import _select_route
|
||||
|
||||
high_benchmark = _make_node("bench-fast", 0, 11, bench=100.0, queue_depth=0)
|
||||
observed_fast = _make_node("observed-fast", 0, 11, bench=1.0, queue_depth=0)
|
||||
high_benchmark.model_tokens_per_sec["m"] = 10.0
|
||||
observed_fast.model_tokens_per_sec["m"] = 40.0
|
||||
|
||||
route, err = _select_route([high_benchmark, observed_fast], 0, 11, model="m")
|
||||
assert err == ""
|
||||
assert route[0].node_id == "observed-fast"
|
||||
|
||||
|
||||
def test_select_route_throughput_accounts_for_queue_depth():
|
||||
"""A nominally faster node with high queue depth loses to a slower idle node."""
|
||||
from meshnet_tracker.server import _select_route
|
||||
|
||||
Reference in New Issue
Block a user