Browse Source

perf(node): sync up to 32 nodes at once, like the heartbeat

The traffic sync is scheduled every 5s but synced only 8 nodes at a time,
each needing four to seven sequential requests. Past about 125 nodes 80ms
away a tick outlasted its interval, so dashboard traffic, online clients
and quota enforcement moved at a fraction of the intended cadence.

Measured with 150-300 fake nodes over real HTTP, 80ms latency, a dashboard
connected and client-IP sync on:

  SQLite, 300 nodes        8: 25-30s   16: 14-16s   32: 6-9.5s
  SQLite, 150 (20% slow)   8: 24-27s   16: 13-14s   32: 6-7.5s
  Postgres, 150 nodes      8: 13-18s   16: 7.5-10s  32: 6.5-8.3s

No database-locked, pool or writer-queue errors at any setting, and the
merged inbound and client traffic counts matched. Postgres's one-off
adoption tick is slower at 32 than at 16 (16.5s vs 9.7s) as goroutines
wait on its 25-connection pool; steady ticks are fastest at 32.
Sanaei 15 hours ago
parent
commit
3c8cf35734
1 changed files with 3 additions and 1 deletions
  1. 3 1
      internal/web/job/node_traffic_sync_job.go

+ 3 - 1
internal/web/job/node_traffic_sync_job.go

@@ -16,7 +16,9 @@ import (
 )
 )
 
 
 const (
 const (
-	nodeTrafficSyncConcurrency    = 8
+	// The heartbeat's bound: at 8, 300 nodes 80ms away took 25-30s per 5s tick on SQLite
+	// and 6-9s at 32; neither SQLite nor Postgres raised lock or pool errors.
+	nodeTrafficSyncConcurrency    = 32
 	nodeTrafficSyncRequestTimeout = 4 * time.Second
 	nodeTrafficSyncRequestTimeout = 4 * time.Second
 	nodeReconcileTimeout          = 30 * time.Second
 	nodeReconcileTimeout          = 30 * time.Second
 	nodeClientIpSyncInterval      = 10 * time.Second
 	nodeClientIpSyncInterval      = 10 * time.Second