2026-04-02 23:35:53 +08:00
|
|
|
package engine
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"errors"
|
2026-04-03 07:46:16 +08:00
|
|
|
"sync"
|
2026-04-02 23:35:53 +08:00
|
|
|
|
|
|
|
|
"lijiaoqiao/gateway/internal/router/strategy"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// ErrStrategyNotFound 策略未找到
|
|
|
|
|
var ErrStrategyNotFound = errors.New("strategy not found")
|
|
|
|
|
|
|
|
|
|
// RoutingMetrics 路由指标接口
|
|
|
|
|
type RoutingMetrics interface {
|
|
|
|
|
// RecordSelection 记录路由选择
|
|
|
|
|
RecordSelection(provider string, strategyName string, decision *strategy.RoutingDecision)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RoutingEngine 路由引擎
|
|
|
|
|
type RoutingEngine struct {
|
2026-04-03 07:46:16 +08:00
|
|
|
mu sync.RWMutex
|
2026-04-02 23:35:53 +08:00
|
|
|
strategies map[string]strategy.StrategyTemplate
|
|
|
|
|
metrics RoutingMetrics
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewRoutingEngine 创建路由引擎
|
|
|
|
|
func NewRoutingEngine() *RoutingEngine {
|
|
|
|
|
return &RoutingEngine{
|
|
|
|
|
strategies: make(map[string]strategy.StrategyTemplate),
|
|
|
|
|
metrics: nil,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RegisterStrategy 注册路由策略
|
|
|
|
|
func (e *RoutingEngine) RegisterStrategy(name string, template strategy.StrategyTemplate) {
|
2026-04-03 07:46:16 +08:00
|
|
|
e.mu.Lock()
|
|
|
|
|
defer e.mu.Unlock()
|
2026-04-02 23:35:53 +08:00
|
|
|
e.strategies[name] = template
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SetMetrics 设置指标收集器
|
|
|
|
|
func (e *RoutingEngine) SetMetrics(metrics RoutingMetrics) {
|
|
|
|
|
e.metrics = metrics
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectProvider 根据策略选择Provider
|
|
|
|
|
func (e *RoutingEngine) SelectProvider(ctx context.Context, req *strategy.RoutingRequest, strategyName string) (*strategy.RoutingDecision, error) {
|
|
|
|
|
// 查找策略
|
|
|
|
|
tpl, ok := e.strategies[strategyName]
|
|
|
|
|
if !ok {
|
|
|
|
|
return nil, ErrStrategyNotFound
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 执行策略选择
|
|
|
|
|
decision, err := tpl.SelectProvider(ctx, req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-03 07:46:16 +08:00
|
|
|
if decision == nil {
|
|
|
|
|
return nil, ErrStrategyNotFound
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if e.metrics != nil {
|
2026-04-02 23:35:53 +08:00
|
|
|
e.metrics.RecordSelection(decision.Provider, decision.Strategy, decision)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return decision, nil
|
|
|
|
|
}
|