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
37 lines
1.1 KiB
Go
37 lines
1.1 KiB
Go
package esl
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// RouteCacheEntry — запись для кэширования маршрута в FS global variable и файле.
|
|
type RouteCacheEntry struct {
|
|
NodeID string `json:"node_id,omitempty"`
|
|
SIPGateway string `json:"sip_gateway,omitempty"`
|
|
Score float64 `json:"score,omitempty"`
|
|
Fallback bool `json:"fallback,omitempty"`
|
|
Reason string `json:"reason,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
TS int64 `json:"ts"`
|
|
}
|
|
|
|
// PushRoute пушит текущий маршрут в FreeSWITCH через global variable.
|
|
// Если клиент не подключён — возвращает ошибку молча (вызывающий игнорирует).
|
|
func PushRoute(c *Client, entry RouteCacheEntry) error {
|
|
if c == nil || !c.IsConnected() {
|
|
return fmt.Errorf("esl не подключён")
|
|
}
|
|
|
|
entry.TS = time.Now().Unix()
|
|
|
|
jsonBytes, err := json.Marshal(entry)
|
|
if err != nil {
|
|
return fmt.Errorf("маршалинг route cache: %w", err)
|
|
}
|
|
|
|
cmd := fmt.Sprintf("api set_global pulse_route_json=%s", string(jsonBytes))
|
|
return c.SendAsync(cmd)
|
|
}
|