Files
neuron-tai/packages/tracker/meshnet_tracker/cli.py
Dobromir Popov 748d535c46 feat(us-019): distributed tracker consensus — Raft assignments + CRDT gossip
raft.py: minimal Raft consensus for shard-assignment log
  - Leader election with random 150–300ms election timeouts
  - AppendEntries log replication; majority commit required
  - RequestVote RPC with log-completeness check
  - Follower registration forwarded to leader via HTTP proxy

gossip.py: LWW CRDT gossip for inference-node heartbeat liveness
  - Each tracker keeps {node_id → wall_clock_timestamp}
  - Merges incoming gossip by taking max per key
  - Pushes snapshot to random peer every 3 seconds

server.py + cli.py:
  - TrackerServer gains cluster_peers + cluster_self_url params
  - New HTTP endpoints: /v1/raft/vote, /v1/raft/append,
    /v1/raft/status, /v1/gossip
  - --cluster-peers and --self-url CLI flags

tests/test_tracker_consensus.py: 6 integration tests
  - Leader elected within 1s
  - Follower registration propagated to all nodes
  - Follower proxy to leader
  - Leader kill → new election within 5s, registrations continue
  - Gossip table updated on heartbeat

92 tests pass, 1 skipped.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 09:05:21 +03:00

62 lines
1.9 KiB
Python

"""meshnet-tracker CLI entry point."""
import argparse
import sys
import time
from .server import TrackerServer
def main() -> None:
parser = argparse.ArgumentParser(
prog="meshnet-tracker",
description="Distributed Inference Network node registry and route selection",
)
subparsers = parser.add_subparsers(dest="command")
start_cmd = subparsers.add_parser("start", help="Start the tracker server")
start_cmd.add_argument("--host", default="127.0.0.1", help="Host interface to listen on")
start_cmd.add_argument("--port", type=int, default=8080, help="Port to listen on")
start_cmd.add_argument(
"--heartbeat-timeout",
type=float,
default=30.0,
help="Seconds before a node is removed from the registry after missed heartbeat",
)
start_cmd.add_argument(
"--cluster-peers",
default="",
help="Comma-separated URLs of peer tracker nodes (enables Raft cluster mode)",
)
start_cmd.add_argument(
"--self-url",
default=None,
help="This tracker's own URL as seen by peers (auto-derived from --host/--port if omitted)",
)
args = parser.parse_args()
if args.command == "start":
cluster_peers = [u.strip() for u in args.cluster_peers.split(",") if u.strip()]
server = TrackerServer(
host=args.host,
port=args.port,
heartbeat_timeout=args.heartbeat_timeout,
cluster_peers=cluster_peers or None,
cluster_self_url=args.self_url,
)
port = server.start()
print(f"meshnet-tracker listening on http://{args.host}:{port}", flush=True)
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
server.stop()
sys.exit(0)
else:
parser.print_help()
if __name__ == "__main__":
main()