74 lines
2.1 KiB
Markdown
74 lines
2.1 KiB
Markdown
# Scoring Engine
|
||
|
||
Вычисляет score (0..100) для каждой ноды. Ноды со score = -100 исключаются из роутинга.
|
||
|
||
## Lethal Conditions (score → -100)
|
||
|
||
Если хотя бы одно условие истинно — нода исключается:
|
||
If at least one is true — node is excluded from routing.
|
||
|
||
| Condition | Threshold |
|
||
|-----------|-----------|
|
||
| `status != "ok"` | Any status other than `ok` |
|
||
| Stale | > `stale_threshold_sec` (default 20s) |
|
||
| `active_calls >= max_calls` | 100% capacity used |
|
||
| `idle_cpu < idle_cpu_min` | < 5% |
|
||
| `call_failure_rate > call_failure_rate_lethal` | > 15% |
|
||
| `disabled == true` | Manual admin disable |
|
||
|
||
## Weighted Score (0..100)
|
||
|
||
```
|
||
call_score = clamp(100 - (active_calls / max_calls * 100), 0, 100)
|
||
load_score = clamp(100 - (load_avg * 50), 0, 100)
|
||
idle_score = clamp(idle_cpu, 0, 100)
|
||
fail_score = clamp(100 - call_failure_rate, 0, 100)
|
||
|
||
score = call_score × 0.40 +
|
||
load_score × 0.30 +
|
||
idle_score × 0.20 +
|
||
fail_score × 0.10
|
||
```
|
||
|
||
Weight defaults (configurable in `config.json`): call 40%, load 30%, idle 20%, fail 10%.
|
||
|
||
## Example
|
||
|
||
Node `pbx-01`: `active_calls=42`, `max_calls=250`, `load_avg=0.85`, `idle_cpu=35`, `fail_rate=0.5`
|
||
|
||
```
|
||
call_score = clamp(100 - (42/250)*100, 0, 100) = 83.2
|
||
load_score = clamp(100 - 0.85*50, 0, 100) = 57.5
|
||
idle_score = clamp(35, 0, 100) = 35.0
|
||
fail_score = clamp(100 - 0.5, 0, 100) = 99.5
|
||
|
||
score = 83.2×0.40 + 57.5×0.30 + 35.0×0.20 + 99.5×0.10 = 70.1
|
||
```
|
||
|
||
## Caching
|
||
|
||
`best_node_id`, `best_score`, and `fallback_active` are recalculated on every metric update.
|
||
`/api/route` reads them under RLock — O(1) constant time.
|
||
|
||
Выбор ноды из кэша зависит от [режима балансировки](routing.md#balancing-modes).
|
||
|
||
## Configuration
|
||
|
||
```json
|
||
{
|
||
"stale_threshold_sec": 20,
|
||
"scoring": {
|
||
"idle_cpu_min": 5,
|
||
"call_failure_rate_lethal": 15.0,
|
||
"weights": {
|
||
"call_score": 0.40,
|
||
"load_score": 0.30,
|
||
"idle_score": 0.20,
|
||
"fail_score": 0.10
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
Weights must sum to 1.0. All thresholds configurable in `config.json`.
|