feat(us-027/us-028): throughput-optimized routing + correctness tests
_select_route now prefers nodes with higher effective throughput (benchmark_tokens_per_sec / (queue_depth + 1)) when multiple nodes cover the same interval, breaking the tie after max-reach selection. TorchNodeServer.route_timeout property added for external inspection. Tests added: - _select_route with overlapping shards (A:0-22, B:20-24) → correct X-Meshnet-Start-Layer protocol - _select_route with gap → clear error message - Fast node beats slow node when shards are equal - Busy fast node vs idle slow node (queue_depth factor) - Two-StubNodeServer integration via TrackerServer - route_timeout property exposed on TorchNodeServer Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -628,6 +628,10 @@ class TorchNodeServer:
|
||||
self._thread: threading.Thread | None = None
|
||||
self.port: int | None = None
|
||||
|
||||
@property
|
||||
def route_timeout(self) -> float:
|
||||
return self._route_timeout
|
||||
|
||||
@property
|
||||
def backend(self) -> TorchModelShard:
|
||||
return self._backend
|
||||
|
||||
@@ -292,12 +292,22 @@ class _NodeEntry:
|
||||
self.pending_new_assignment: dict | None = None
|
||||
|
||||
|
||||
def _effective_throughput(node: "_NodeEntry") -> float:
|
||||
"""Effective tokens/s accounting for current queue depth."""
|
||||
return node.benchmark_tokens_per_sec / (node.queue_depth + 1)
|
||||
|
||||
|
||||
def _select_route(
|
||||
nodes: list[_NodeEntry],
|
||||
required_start: int,
|
||||
required_end: int,
|
||||
) -> tuple[list[_NodeEntry], str]:
|
||||
"""Greedy interval-cover. Returns (ordered route, error_message)."""
|
||||
"""Greedy interval-cover biased toward fast, lightly-loaded nodes.
|
||||
|
||||
Among nodes that equally advance coverage, prefer the one with higher
|
||||
effective throughput: benchmark_tokens_per_sec / (queue_depth + 1).
|
||||
Tiebreak: higher shard_end (fewer hops).
|
||||
"""
|
||||
candidates = sorted(
|
||||
[node for node in nodes if node.shard_start is not None and node.shard_end is not None],
|
||||
key=lambda n: (n.shard_start, -n.shard_end), # type: ignore[operator]
|
||||
@@ -309,7 +319,11 @@ def _select_route(
|
||||
best: _NodeEntry | None = None
|
||||
for node in candidates:
|
||||
if node.shard_start <= covered_up_to + 1 and node.shard_end > covered_up_to:
|
||||
if best is None or node.shard_end > best.shard_end:
|
||||
if best is None:
|
||||
best = node
|
||||
elif node.shard_end > best.shard_end:
|
||||
best = node
|
||||
elif node.shard_end == best.shard_end and _effective_throughput(node) > _effective_throughput(best):
|
||||
best = node
|
||||
if best is None:
|
||||
missing = covered_up_to + 1
|
||||
|
||||
Reference in New Issue
Block a user