ProxyProvider health check also supports specifying expected status (#600)
Co-authored-by: wwqgtxx <wwqgtxx@gmail.com>
This commit is contained in:
parent
3ef81afc76
commit
3c1f9a9953
@ -81,7 +81,7 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide
|
|||||||
return nil, errDuplicateProvider
|
return nil, errDuplicateProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
hc := provider.NewHealthCheck(ps, "", 0, true)
|
hc := provider.NewHealthCheck(ps, "", 0, true, nil)
|
||||||
pd, err := provider.NewCompatibleProvider(groupName, ps, hc)
|
pd, err := provider.NewCompatibleProvider(groupName, ps, hc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -39,6 +39,7 @@ type HealthCheck struct {
|
|||||||
proxies []C.Proxy
|
proxies []C.Proxy
|
||||||
interval uint
|
interval uint
|
||||||
lazy bool
|
lazy bool
|
||||||
|
expectedStatus utils.IntRanges[uint16]
|
||||||
lastTouch *atomic.Int64
|
lastTouch *atomic.Int64
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
singleDo *singledo.Single[struct{}]
|
singleDo *singledo.Single[struct{}]
|
||||||
@ -153,7 +154,8 @@ func (hc *HealthCheck) check() {
|
|||||||
b, _ := batch.New[bool](context.Background(), batch.WithConcurrencyNum[bool](10))
|
b, _ := batch.New[bool](context.Background(), batch.WithConcurrencyNum[bool](10))
|
||||||
|
|
||||||
// execute default health check
|
// execute default health check
|
||||||
hc.execute(b, hc.url, id, nil)
|
option := &extraOption{filters: nil, expectedStatus: hc.expectedStatus}
|
||||||
|
hc.execute(b, hc.url, id, option)
|
||||||
|
|
||||||
// execute extra health check
|
// execute extra health check
|
||||||
if len(hc.extra) != 0 {
|
if len(hc.extra) != 0 {
|
||||||
@ -178,7 +180,10 @@ func (hc *HealthCheck) execute(b *batch.Batch[bool], url, uid string, option *ex
|
|||||||
var store = C.OriginalHistory
|
var store = C.OriginalHistory
|
||||||
var expectedStatus utils.IntRanges[uint16]
|
var expectedStatus utils.IntRanges[uint16]
|
||||||
if option != nil {
|
if option != nil {
|
||||||
|
if url != hc.url {
|
||||||
store = C.ExtraHistory
|
store = C.ExtraHistory
|
||||||
|
}
|
||||||
|
|
||||||
expectedStatus = option.expectedStatus
|
expectedStatus = option.expectedStatus
|
||||||
if len(option.filters) != 0 {
|
if len(option.filters) != 0 {
|
||||||
filters := make([]string, 0, len(option.filters))
|
filters := make([]string, 0, len(option.filters))
|
||||||
@ -214,7 +219,7 @@ func (hc *HealthCheck) close() {
|
|||||||
hc.done <- struct{}{}
|
hc.done <- struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHealthCheck(proxies []C.Proxy, url string, interval uint, lazy bool) *HealthCheck {
|
func NewHealthCheck(proxies []C.Proxy, url string, interval uint, lazy bool, expectedStatus utils.IntRanges[uint16]) *HealthCheck {
|
||||||
return &HealthCheck{
|
return &HealthCheck{
|
||||||
proxies: proxies,
|
proxies: proxies,
|
||||||
url: url,
|
url: url,
|
||||||
@ -222,6 +227,7 @@ func NewHealthCheck(proxies []C.Proxy, url string, interval uint, lazy bool) *He
|
|||||||
started: atomic.NewBool(false),
|
started: atomic.NewBool(false),
|
||||||
interval: interval,
|
interval: interval,
|
||||||
lazy: lazy,
|
lazy: lazy,
|
||||||
|
expectedStatus: expectedStatus,
|
||||||
lastTouch: atomic.NewInt64(0),
|
lastTouch: atomic.NewInt64(0),
|
||||||
done: make(chan struct{}, 1),
|
done: make(chan struct{}, 1),
|
||||||
singleDo: singledo.NewSingle[struct{}](time.Second),
|
singleDo: singledo.NewSingle[struct{}](time.Second),
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/structure"
|
"github.com/Dreamacro/clash/common/structure"
|
||||||
|
"github.com/Dreamacro/clash/common/utils"
|
||||||
"github.com/Dreamacro/clash/component/resource"
|
"github.com/Dreamacro/clash/component/resource"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
types "github.com/Dreamacro/clash/constant/provider"
|
types "github.com/Dreamacro/clash/constant/provider"
|
||||||
@ -18,6 +19,7 @@ type healthCheckSchema struct {
|
|||||||
URL string `provider:"url"`
|
URL string `provider:"url"`
|
||||||
Interval int `provider:"interval"`
|
Interval int `provider:"interval"`
|
||||||
Lazy bool `provider:"lazy,omitempty"`
|
Lazy bool `provider:"lazy,omitempty"`
|
||||||
|
ExpectedStatus string `provider:"expected-status,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type proxyProviderSchema struct {
|
type proxyProviderSchema struct {
|
||||||
@ -44,11 +46,16 @@ func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvide
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expectedStatus, err := utils.NewIntRanges[uint16](schema.HealthCheck.ExpectedStatus)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var hcInterval uint
|
var hcInterval uint
|
||||||
if schema.HealthCheck.Enable {
|
if schema.HealthCheck.Enable {
|
||||||
hcInterval = uint(schema.HealthCheck.Interval)
|
hcInterval = uint(schema.HealthCheck.Interval)
|
||||||
}
|
}
|
||||||
hc := NewHealthCheck([]C.Proxy{}, schema.HealthCheck.URL, hcInterval, schema.HealthCheck.Lazy)
|
hc := NewHealthCheck([]C.Proxy{}, schema.HealthCheck.URL, hcInterval, schema.HealthCheck.Lazy, expectedStatus)
|
||||||
|
|
||||||
path := C.Path.Resolve(schema.Path)
|
path := C.Path.Resolve(schema.Path)
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[
|
|||||||
}
|
}
|
||||||
ps = append(ps, proxies[v])
|
ps = append(ps, proxies[v])
|
||||||
}
|
}
|
||||||
hc := provider.NewHealthCheck(ps, "", 0, true)
|
hc := provider.NewHealthCheck(ps, "", 0, true, nil)
|
||||||
pd, _ := provider.NewCompatibleProvider(provider.ReservedName, ps, hc)
|
pd, _ := provider.NewCompatibleProvider(provider.ReservedName, ps, hc)
|
||||||
providersMap[provider.ReservedName] = pd
|
providersMap[provider.ReservedName] = pd
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user