feat: production-grade routing cache + stale detection fixes
Three-tier routing cache (ESL global -> file -> HTTP) eliminates HTTP
from call path for 2500-5000 concurrent calls. Lua reads cached route
in ~0.1us instead of blocking on api:execute('curl', ...).
Engine fixes:
- recalcBestLocked now skips stale nodes (was 5 min bug -> now ~10-15s)
- PickNodeForCall action_type='node' checks staleness for consistency
- onMetric callback pushes cache on every metric (no ticker delay)
Config:
- stale_threshold_sec default 20 -> 10 (industry standard)
- contrib/ included in Makefile deploy target
- route.lua paths updated for /opt/pulse-lets-go
This commit is contained in:
@@ -456,12 +456,18 @@ func (e *Engine) scoreNodeLocked(ns *models.NodeState, firstMetric bool) {
|
||||
|
||||
// recalcBestLocked пересчитывает кэш лучшей ноды.
|
||||
// Вызывающий держит write lock.
|
||||
// Проверяет staleness (now - ns.TS > staleThreshold) — исключает ноды без свежих метрик.
|
||||
func (e *Engine) recalcBestLocked() {
|
||||
bestID := ""
|
||||
bestScore := -999.0
|
||||
anyHealthy := false
|
||||
now := time.Now().Unix()
|
||||
staleThreshold := int64(e.cfg.StaleThresholdSec)
|
||||
|
||||
for id, ns := range e.nodes {
|
||||
if now-ns.TS > staleThreshold {
|
||||
continue
|
||||
}
|
||||
if ns.Score >= 0 {
|
||||
anyHealthy = true
|
||||
}
|
||||
|
||||
@@ -318,8 +318,10 @@ func (e *Engine) PickNodeForCall(callerID, dest, ingress string) (nodeID string,
|
||||
case "node":
|
||||
e.mu.RLock()
|
||||
ns, ok := e.nodes[cr.ActionNodeID]
|
||||
now := time.Now().Unix()
|
||||
staleThreshold := int64(e.cfg.StaleThresholdSec)
|
||||
e.mu.RUnlock()
|
||||
if ok && ns.Score >= 0 {
|
||||
if ok && ns.Score >= 0 && now-ns.TS <= staleThreshold {
|
||||
nodeID, score, matchedRule = cr.ActionNodeID, 100, cr.Name
|
||||
resolved = true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user