57 lines
1.6 KiB
Go
57 lines
1.6 KiB
Go
package runner
|
|
|
|
import (
|
|
"sort"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// ValidatorTiming records domain validator work without treating a scheduler
|
|
// permit or provider attempt as a logical LLM call.
|
|
type ValidatorTiming struct {
|
|
ModuleKey string `json:"module_key"`
|
|
ModuleInstance string `json:"module_instance"`
|
|
ValidatorName string `json:"validator_name"`
|
|
LLMBacked bool `json:"llm_backed"`
|
|
Calls int `json:"calls"`
|
|
ElapsedMS int64 `json:"elapsed_ms"`
|
|
}
|
|
|
|
type validatorTimingCollector struct {
|
|
mu sync.Mutex
|
|
byKey map[string]*ValidatorTiming
|
|
}
|
|
|
|
func newValidatorTimingCollector() *validatorTimingCollector {
|
|
return &validatorTimingCollector{byKey: make(map[string]*ValidatorTiming)}
|
|
}
|
|
|
|
func (c *validatorTimingCollector) record(moduleKey, moduleInstance, validatorName string, llmBacked bool, elapsed time.Duration) {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
key := moduleInstance + "\x00" + validatorName
|
|
timing := c.byKey[key]
|
|
if timing == nil {
|
|
timing = &ValidatorTiming{ModuleKey: moduleKey, ModuleInstance: moduleInstance, ValidatorName: validatorName, LLMBacked: llmBacked}
|
|
c.byKey[key] = timing
|
|
}
|
|
timing.Calls++
|
|
timing.ElapsedMS += elapsed.Milliseconds()
|
|
}
|
|
|
|
func (c *validatorTimingCollector) snapshot() []ValidatorTiming {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
result := make([]ValidatorTiming, 0, len(c.byKey))
|
|
for _, timing := range c.byKey {
|
|
result = append(result, *timing)
|
|
}
|
|
sort.Slice(result, func(i, j int) bool {
|
|
if result[i].ModuleInstance != result[j].ModuleInstance {
|
|
return result[i].ModuleInstance < result[j].ModuleInstance
|
|
}
|
|
return result[i].ValidatorName < result[j].ValidatorName
|
|
})
|
|
return result
|
|
}
|