Merge remote-tracking branch 'clash/dev' into Alpha
# Conflicts: # .github/workflows/docker.yml # adapter/outboundgroup/fallback.go # adapter/outboundgroup/loadbalance.go # adapter/outboundgroup/relay.go # adapter/outboundgroup/selector.go # adapter/outboundgroup/urltest.go # config/config.go # go.mod # go.sum # main.go # test/go.mod # test/go.sum
This commit is contained in:
commit
50ab57c72e
70 changed files with 241 additions and 255 deletions
|
@ -2,7 +2,7 @@ linters:
|
||||||
disable-all: true
|
disable-all: true
|
||||||
enable:
|
enable:
|
||||||
- gofumpt
|
- gofumpt
|
||||||
- megacheck
|
- staticcheck
|
||||||
- govet
|
- govet
|
||||||
- gci
|
- gci
|
||||||
|
|
||||||
|
@ -12,3 +12,5 @@ linters-settings:
|
||||||
- standard
|
- standard
|
||||||
- prefix(github.com/Dreamacro/clash)
|
- prefix(github.com/Dreamacro/clash)
|
||||||
- default
|
- default
|
||||||
|
staticcheck:
|
||||||
|
go: '1.18'
|
||||||
|
|
10
Makefile
10
Makefile
|
@ -41,10 +41,10 @@ all:linux-amd64\
|
||||||
linux-mips-hardfloat linux-mips-softfloat linux-mips64 linux-mips64le linux-mipsle-hardfloat linux-mipsle-softfloat# Most used
|
linux-mips-hardfloat linux-mips-softfloat linux-mips64 linux-mips64le linux-mipsle-hardfloat linux-mipsle-softfloat# Most used
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
$(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
GOAMD64=v3 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
||||||
|
|
||||||
darwin-amd64:
|
darwin-amd64:
|
||||||
GOARCH=amd64 GOOS=darwin $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
GOARCH=amd64 GOOS=darwin GOAMD64=v3 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
||||||
|
|
||||||
darwin-arm64:
|
darwin-arm64:
|
||||||
GOARCH=arm64 GOOS=darwin $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
GOARCH=arm64 GOOS=darwin $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
||||||
|
@ -53,7 +53,7 @@ linux-386:
|
||||||
GOARCH=386 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
GOARCH=386 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
||||||
|
|
||||||
linux-amd64:
|
linux-amd64:
|
||||||
GOARCH=amd64 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
GOARCH=amd64 GOOS=linux GOAMD64=v3 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
||||||
|
|
||||||
linux-amd64-AutoIptables:
|
linux-amd64-AutoIptables:
|
||||||
GOARCH=amd64 GOOS=linux $(GOBUILDOP) -o $(BINDIR)/$(NAME)-$@
|
GOARCH=amd64 GOOS=linux $(GOBUILDOP) -o $(BINDIR)/$(NAME)-$@
|
||||||
|
@ -98,7 +98,7 @@ freebsd-386:
|
||||||
GOARCH=386 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
GOARCH=386 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
||||||
|
|
||||||
freebsd-amd64:
|
freebsd-amd64:
|
||||||
GOARCH=amd64 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
GOARCH=amd64 GOOS=freebsd GOAMD64=v3 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
||||||
|
|
||||||
freebsd-arm64:
|
freebsd-arm64:
|
||||||
GOARCH=arm64 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
GOARCH=arm64 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
|
||||||
|
@ -107,7 +107,7 @@ windows-386:
|
||||||
GOARCH=386 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
|
GOARCH=386 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
|
||||||
|
|
||||||
windows-amd64:
|
windows-amd64:
|
||||||
GOARCH=amd64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
|
GOARCH=amd64 GOOS=windows GOAMD64=v3 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
|
||||||
|
|
||||||
windows-arm64:
|
windows-arm64:
|
||||||
GOARCH=arm64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
|
GOARCH=arm64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
|
||||||
|
|
|
@ -93,7 +93,7 @@ func (p *Proxy) MarshalJSON() ([]byte, error) {
|
||||||
return inner, err
|
return inner, err
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping := map[string]interface{}{}
|
mapping := map[string]any{}
|
||||||
json.Unmarshal(inner, &mapping)
|
json.Unmarshal(inner, &mapping)
|
||||||
mapping["history"] = p.DelayHistory()
|
mapping["history"] = p.DelayHistory()
|
||||||
mapping["name"] = p.Name()
|
mapping["name"] = p.Name()
|
||||||
|
|
|
@ -36,7 +36,7 @@ type ShadowSocksOption struct {
|
||||||
Cipher string `proxy:"cipher"`
|
Cipher string `proxy:"cipher"`
|
||||||
UDP bool `proxy:"udp,omitempty"`
|
UDP bool `proxy:"udp,omitempty"`
|
||||||
Plugin string `proxy:"plugin,omitempty"`
|
Plugin string `proxy:"plugin,omitempty"`
|
||||||
PluginOpts map[string]interface{} `proxy:"plugin-opts,omitempty"`
|
PluginOpts map[string]any `proxy:"plugin-opts,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type simpleObfsOption struct {
|
type simpleObfsOption struct {
|
||||||
|
|
|
@ -29,7 +29,7 @@ type SnellOption struct {
|
||||||
Psk string `proxy:"psk"`
|
Psk string `proxy:"psk"`
|
||||||
UDP bool `proxy:"udp,omitempty"`
|
UDP bool `proxy:"udp,omitempty"`
|
||||||
Version int `proxy:"version,omitempty"`
|
Version int `proxy:"version,omitempty"`
|
||||||
ObfsOpts map[string]interface{} `proxy:"obfs-opts,omitempty"`
|
ObfsOpts map[string]any `proxy:"obfs-opts,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type streamOption struct {
|
type streamOption struct {
|
||||||
|
|
|
@ -97,12 +97,11 @@ func (f *Fallback) SupportUDP() bool {
|
||||||
|
|
||||||
// MarshalJSON implements C.ProxyAdapter
|
// MarshalJSON implements C.ProxyAdapter
|
||||||
func (f *Fallback) MarshalJSON() ([]byte, error) {
|
func (f *Fallback) MarshalJSON() ([]byte, error) {
|
||||||
all := make([]string, 0)
|
var all []string
|
||||||
for _, proxy := range f.proxies(false) {
|
for _, proxy := range f.proxies(false) {
|
||||||
all = append(all, proxy.Name())
|
all = append(all, proxy.Name())
|
||||||
}
|
}
|
||||||
|
return json.Marshal(map[string]any{
|
||||||
return json.Marshal(map[string]interface{}{
|
|
||||||
"type": f.Type().String(),
|
"type": f.Type().String(),
|
||||||
"now": f.Now(),
|
"now": f.Now(),
|
||||||
"all": all,
|
"all": all,
|
||||||
|
@ -116,8 +115,8 @@ func (f *Fallback) Unwrap(metadata *C.Metadata) C.Proxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Fallback) proxies(touch bool) []C.Proxy {
|
func (f *Fallback) proxies(touch bool) []C.Proxy {
|
||||||
elm, _, _ := f.single.Do(func() (interface{}, error) {
|
elm, _, _ := f.single.Do(func() (any, error) {
|
||||||
return getProvidersProxies(f.providers, touch, f.filter), nil
|
return getProvidersProxies(f.providers, touch), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return elm.([]C.Proxy)
|
return elm.([]C.Proxy)
|
||||||
|
|
|
@ -30,7 +30,7 @@ type LoadBalance struct {
|
||||||
|
|
||||||
var errStrategy = errors.New("unsupported strategy")
|
var errStrategy = errors.New("unsupported strategy")
|
||||||
|
|
||||||
func parseStrategy(config map[string]interface{}) string {
|
func parseStrategy(config map[string]any) string {
|
||||||
if elm, ok := config["strategy"]; ok {
|
if elm, ok := config["strategy"]; ok {
|
||||||
if strategy, ok := elm.(string); ok {
|
if strategy, ok := elm.(string); ok {
|
||||||
return strategy
|
return strategy
|
||||||
|
@ -141,7 +141,7 @@ func (lb *LoadBalance) Unwrap(metadata *C.Metadata) C.Proxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lb *LoadBalance) proxies(touch bool) []C.Proxy {
|
func (lb *LoadBalance) proxies(touch bool) []C.Proxy {
|
||||||
elm, _, _ := lb.single.Do(func() (interface{}, error) {
|
elm, _, _ := lb.single.Do(func() (any, error) {
|
||||||
return getProvidersProxies(lb.providers, touch, lb.filter), nil
|
return getProvidersProxies(lb.providers, touch, lb.filter), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -150,13 +150,11 @@ func (lb *LoadBalance) proxies(touch bool) []C.Proxy {
|
||||||
|
|
||||||
// MarshalJSON implements C.ProxyAdapter
|
// MarshalJSON implements C.ProxyAdapter
|
||||||
func (lb *LoadBalance) MarshalJSON() ([]byte, error) {
|
func (lb *LoadBalance) MarshalJSON() ([]byte, error) {
|
||||||
all := make([]string, 0)
|
var all []string
|
||||||
|
|
||||||
for _, proxy := range lb.proxies(false) {
|
for _, proxy := range lb.proxies(false) {
|
||||||
all = append(all, proxy.Name())
|
all = append(all, proxy.Name())
|
||||||
}
|
}
|
||||||
|
return json.Marshal(map[string]any{
|
||||||
return json.Marshal(map[string]interface{}{
|
|
||||||
"type": lb.Type().String(),
|
"type": lb.Type().String(),
|
||||||
"all": all,
|
"all": all,
|
||||||
})
|
})
|
||||||
|
|
|
@ -32,7 +32,7 @@ type GroupCommonOption struct {
|
||||||
Filter string `group:"filter,omitempty"`
|
Filter string `group:"filter,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseProxyGroup(config map[string]interface{}, proxyMap map[string]C.Proxy, providersMap map[string]types.ProxyProvider) (C.ProxyAdapter, error) {
|
func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, providersMap map[string]types.ProxyProvider) (C.ProxyAdapter, error) {
|
||||||
decoder := structure.NewDecoder(structure.Option{TagName: "group", WeaklyTypedInput: true})
|
decoder := structure.NewDecoder(structure.Option{TagName: "group", WeaklyTypedInput: true})
|
||||||
|
|
||||||
groupOption := &GroupCommonOption{
|
groupOption := &GroupCommonOption{
|
||||||
|
|
|
@ -69,20 +69,18 @@ func (r *Relay) DialContext(ctx context.Context, metadata *C.Metadata, opts ...d
|
||||||
|
|
||||||
// MarshalJSON implements C.ProxyAdapter
|
// MarshalJSON implements C.ProxyAdapter
|
||||||
func (r *Relay) MarshalJSON() ([]byte, error) {
|
func (r *Relay) MarshalJSON() ([]byte, error) {
|
||||||
all := make([]string, 0)
|
var all []string
|
||||||
|
|
||||||
for _, proxy := range r.rawProxies(false) {
|
for _, proxy := range r.rawProxies(false) {
|
||||||
all = append(all, proxy.Name())
|
all = append(all, proxy.Name())
|
||||||
}
|
}
|
||||||
|
return json.Marshal(map[string]any{
|
||||||
return json.Marshal(map[string]interface{}{
|
|
||||||
"type": r.Type().String(),
|
"type": r.Type().String(),
|
||||||
"all": all,
|
"all": all,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Relay) rawProxies(touch bool) []C.Proxy {
|
func (r *Relay) rawProxies(touch bool) []C.Proxy {
|
||||||
elm, _, _ := r.single.Do(func() (interface{}, error) {
|
elm, _, _ := r.single.Do(func() (any, error) {
|
||||||
return getProvidersProxies(r.providers, touch, r.filter), nil
|
return getProvidersProxies(r.providers, touch, r.filter), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -50,13 +50,12 @@ func (s *Selector) SupportUDP() bool {
|
||||||
|
|
||||||
// MarshalJSON implements C.ProxyAdapter
|
// MarshalJSON implements C.ProxyAdapter
|
||||||
func (s *Selector) MarshalJSON() ([]byte, error) {
|
func (s *Selector) MarshalJSON() ([]byte, error) {
|
||||||
all := make([]string, 0)
|
var all []string
|
||||||
|
|
||||||
for _, proxy := range getProvidersProxies(s.providers, false, s.filter) {
|
for _, proxy := range getProvidersProxies(s.providers, false, s.filter) {
|
||||||
all = append(all, proxy.Name())
|
all = append(all, proxy.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
return json.Marshal(map[string]interface{}{
|
return json.Marshal(map[string]any{
|
||||||
"type": s.Type().String(),
|
"type": s.Type().String(),
|
||||||
"now": s.Now(),
|
"now": s.Now(),
|
||||||
"all": all,
|
"all": all,
|
||||||
|
@ -85,7 +84,7 @@ func (s *Selector) Unwrap(metadata *C.Metadata) C.Proxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Selector) selectedProxy(touch bool) C.Proxy {
|
func (s *Selector) selectedProxy(touch bool) C.Proxy {
|
||||||
elm, _, _ := s.single.Do(func() (interface{}, error) {
|
elm, _, _ := s.single.Do(func() (any, error) {
|
||||||
proxies := getProvidersProxies(s.providers, touch, s.filter)
|
proxies := getProvidersProxies(s.providers, touch, s.filter)
|
||||||
for _, proxy := range proxies {
|
for _, proxy := range proxies {
|
||||||
if proxy.Name() == s.selected {
|
if proxy.Name() == s.selected {
|
||||||
|
|
|
@ -49,7 +49,6 @@ func (u *URLTest) DialContext(ctx context.Context, metadata *C.Metadata, opts ..
|
||||||
} else {
|
} else {
|
||||||
u.onDialFailed()
|
u.onDialFailed()
|
||||||
}
|
}
|
||||||
|
|
||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +62,6 @@ func (u *URLTest) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
|
||||||
} else {
|
} else {
|
||||||
u.onDialFailed()
|
u.onDialFailed()
|
||||||
}
|
}
|
||||||
|
|
||||||
return pc, err
|
return pc, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +71,7 @@ func (u *URLTest) Unwrap(metadata *C.Metadata) C.Proxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *URLTest) proxies(touch bool) []C.Proxy {
|
func (u *URLTest) proxies(touch bool) []C.Proxy {
|
||||||
elm, _, _ := u.single.Do(func() (interface{}, error) {
|
elm, _, _ := u.single.Do(func() (any, error) {
|
||||||
return getProvidersProxies(u.providers, touch, u.filter), nil
|
return getProvidersProxies(u.providers, touch, u.filter), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -81,7 +79,7 @@ func (u *URLTest) proxies(touch bool) []C.Proxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *URLTest) fast(touch bool) C.Proxy {
|
func (u *URLTest) fast(touch bool) C.Proxy {
|
||||||
elm, _, _ := u.fastSingle.Do(func() (interface{}, error) {
|
elm, _, _ := u.fastSingle.Do(func() (any, error) {
|
||||||
proxies := u.proxies(touch)
|
proxies := u.proxies(touch)
|
||||||
fast := proxies[0]
|
fast := proxies[0]
|
||||||
min := fast.LastDelay()
|
min := fast.LastDelay()
|
||||||
|
@ -125,13 +123,11 @@ func (u *URLTest) SupportUDP() bool {
|
||||||
|
|
||||||
// MarshalJSON implements C.ProxyAdapter
|
// MarshalJSON implements C.ProxyAdapter
|
||||||
func (u *URLTest) MarshalJSON() ([]byte, error) {
|
func (u *URLTest) MarshalJSON() ([]byte, error) {
|
||||||
all := make([]string, 0)
|
var all []string
|
||||||
|
|
||||||
for _, proxy := range u.proxies(false) {
|
for _, proxy := range u.proxies(false) {
|
||||||
all = append(all, proxy.Name())
|
all = append(all, proxy.Name())
|
||||||
}
|
}
|
||||||
|
return json.Marshal(map[string]any{
|
||||||
return json.Marshal(map[string]interface{}{
|
|
||||||
"type": u.Type().String(),
|
"type": u.Type().String(),
|
||||||
"now": u.Now(),
|
"now": u.Now(),
|
||||||
"all": all,
|
"all": all,
|
||||||
|
@ -164,7 +160,7 @@ func (u *URLTest) onDialFailed() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseURLTestOption(config map[string]interface{}) []urlTestOption {
|
func parseURLTestOption(config map[string]any) []urlTestOption {
|
||||||
opts := []urlTestOption{}
|
opts := []urlTestOption{}
|
||||||
|
|
||||||
// tolerance
|
// tolerance
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ParseProxy(mapping map[string]interface{}) (C.Proxy, error) {
|
func ParseProxy(mapping map[string]any) (C.Proxy, error) {
|
||||||
decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true})
|
decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true})
|
||||||
proxyType, existType := mapping["type"].(string)
|
proxyType, existType := mapping["type"].(string)
|
||||||
if !existType {
|
if !existType {
|
||||||
|
|
|
@ -16,7 +16,7 @@ var (
|
||||||
dirMode os.FileMode = 0o755
|
dirMode os.FileMode = 0o755
|
||||||
)
|
)
|
||||||
|
|
||||||
type parser = func([]byte) (interface{}, error)
|
type parser = func([]byte) (any, error)
|
||||||
|
|
||||||
type fetcher struct {
|
type fetcher struct {
|
||||||
name string
|
name string
|
||||||
|
@ -26,7 +26,7 @@ type fetcher struct {
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
hash [16]byte
|
hash [16]byte
|
||||||
parser parser
|
parser parser
|
||||||
onUpdate func(interface{})
|
onUpdate func(any)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fetcher) Name() string {
|
func (f *fetcher) Name() string {
|
||||||
|
@ -37,7 +37,7 @@ func (f *fetcher) VehicleType() types.VehicleType {
|
||||||
return f.vehicle.Type()
|
return f.vehicle.Type()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fetcher) Initial() (interface{}, error) {
|
func (f *fetcher) Initial() (any, error) {
|
||||||
var (
|
var (
|
||||||
buf []byte
|
buf []byte
|
||||||
err error
|
err error
|
||||||
|
@ -92,7 +92,7 @@ func (f *fetcher) Initial() (interface{}, error) {
|
||||||
return proxies, nil
|
return proxies, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fetcher) Update() (interface{}, bool, error) {
|
func (f *fetcher) Update() (any, bool, error) {
|
||||||
buf, err := f.vehicle.Read()
|
buf, err := f.vehicle.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
|
@ -168,7 +168,7 @@ func safeWrite(path string, buf []byte) error {
|
||||||
return os.WriteFile(path, buf, fileMode)
|
return os.WriteFile(path, buf, fileMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFetcher(name string, interval time.Duration, vehicle types.Vehicle, parser parser, onUpdate func(interface{})) *fetcher {
|
func newFetcher(name string, interval time.Duration, vehicle types.Vehicle, parser parser, onUpdate func(any)) *fetcher {
|
||||||
var ticker *time.Ticker
|
var ticker *time.Ticker
|
||||||
if interval != 0 {
|
if interval != 0 {
|
||||||
ticker = time.NewTicker(interval)
|
ticker = time.NewTicker(interval)
|
||||||
|
|
|
@ -62,7 +62,7 @@ func (hc *HealthCheck) check() {
|
||||||
b, _ := batch.New(context.Background(), batch.WithConcurrencyNum(10))
|
b, _ := batch.New(context.Background(), batch.WithConcurrencyNum(10))
|
||||||
for _, proxy := range hc.proxies {
|
for _, proxy := range hc.proxies {
|
||||||
p := proxy
|
p := proxy
|
||||||
b.Go(p.Name(), func() (interface{}, error) {
|
b.Go(p.Name(), func() (any, error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), defaultURLTestTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), defaultURLTestTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
p.URLTest(ctx, hc.url)
|
p.URLTest(ctx, hc.url)
|
||||||
|
|
|
@ -28,7 +28,7 @@ type proxyProviderSchema struct {
|
||||||
HealthCheck healthCheckSchema `provider:"health-check,omitempty"`
|
HealthCheck healthCheckSchema `provider:"health-check,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseProxyProvider(name string, mapping map[string]interface{}) (types.ProxyProvider, error) {
|
func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvider, error) {
|
||||||
decoder := structure.NewDecoder(structure.Option{TagName: "provider", WeaklyTypedInput: true})
|
decoder := structure.NewDecoder(structure.Option{TagName: "provider", WeaklyTypedInput: true})
|
||||||
|
|
||||||
schema := &proxyProviderSchema{
|
schema := &proxyProviderSchema{
|
||||||
|
|
|
@ -20,7 +20,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProxySchema struct {
|
type ProxySchema struct {
|
||||||
Proxies []map[string]interface{} `yaml:"proxies"`
|
Proxies []map[string]any `yaml:"proxies"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// for auto gc
|
// for auto gc
|
||||||
|
@ -35,7 +35,7 @@ type proxySetProvider struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *proxySetProvider) MarshalJSON() ([]byte, error) {
|
func (pp *proxySetProvider) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(map[string]interface{}{
|
return json.Marshal(map[string]any{
|
||||||
"name": pp.Name(),
|
"name": pp.Name(),
|
||||||
"type": pp.Type().String(),
|
"type": pp.Type().String(),
|
||||||
"vehicleType": pp.VehicleType().String(),
|
"vehicleType": pp.VehicleType().String(),
|
||||||
|
@ -112,12 +112,12 @@ func NewProxySetProvider(name string, interval time.Duration, filter string, veh
|
||||||
healthCheck: hc,
|
healthCheck: hc,
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdate := func(elm interface{}) {
|
onUpdate := func(elm any) {
|
||||||
ret := elm.([]C.Proxy)
|
ret := elm.([]C.Proxy)
|
||||||
pd.setProxies(ret)
|
pd.setProxies(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
proxiesParseAndFilter := func(buf []byte) (interface{}, error) {
|
proxiesParseAndFilter := func(buf []byte) (any, error) {
|
||||||
schema := &ProxySchema{}
|
schema := &ProxySchema{}
|
||||||
|
|
||||||
if err := yaml.Unmarshal(buf, schema); err != nil {
|
if err := yaml.Unmarshal(buf, schema); err != nil {
|
||||||
|
@ -172,7 +172,7 @@ type compatibleProvider struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *compatibleProvider) MarshalJSON() ([]byte, error) {
|
func (cp *compatibleProvider) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(map[string]interface{}{
|
return json.Marshal(map[string]any{
|
||||||
"name": cp.Name(),
|
"name": cp.Name(),
|
||||||
"type": cp.Type().String(),
|
"type": cp.Type().String(),
|
||||||
"vehicleType": cp.VehicleType().String(),
|
"vehicleType": cp.VehicleType().String(),
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
type Option = func(b *Batch)
|
type Option = func(b *Batch)
|
||||||
|
|
||||||
type Result struct {
|
type Result struct {
|
||||||
Value interface{}
|
Value any
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ type Batch struct {
|
||||||
cancel func()
|
cancel func()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Batch) Go(key string, fn func() (interface{}, error)) {
|
func (b *Batch) Go(key string, fn func() (any, error)) {
|
||||||
b.wg.Add(1)
|
b.wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer b.wg.Done()
|
defer b.wg.Done()
|
||||||
|
|
|
@ -14,11 +14,11 @@ func TestBatch(t *testing.T) {
|
||||||
b, _ := New(context.Background())
|
b, _ := New(context.Background())
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
b.Go("foo", func() (interface{}, error) {
|
b.Go("foo", func() (any, error) {
|
||||||
time.Sleep(time.Millisecond * 100)
|
time.Sleep(time.Millisecond * 100)
|
||||||
return "foo", nil
|
return "foo", nil
|
||||||
})
|
})
|
||||||
b.Go("bar", func() (interface{}, error) {
|
b.Go("bar", func() (any, error) {
|
||||||
time.Sleep(time.Millisecond * 150)
|
time.Sleep(time.Millisecond * 150)
|
||||||
return "bar", nil
|
return "bar", nil
|
||||||
})
|
})
|
||||||
|
@ -45,7 +45,7 @@ func TestBatchWithConcurrencyNum(t *testing.T) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
for i := 0; i < 7; i++ {
|
for i := 0; i < 7; i++ {
|
||||||
idx := i
|
idx := i
|
||||||
b.Go(strconv.Itoa(idx), func() (interface{}, error) {
|
b.Go(strconv.Itoa(idx), func() (any, error) {
|
||||||
time.Sleep(time.Millisecond * 100)
|
time.Sleep(time.Millisecond * 100)
|
||||||
return strconv.Itoa(idx), nil
|
return strconv.Itoa(idx), nil
|
||||||
})
|
})
|
||||||
|
@ -64,12 +64,12 @@ func TestBatchWithConcurrencyNum(t *testing.T) {
|
||||||
func TestBatchContext(t *testing.T) {
|
func TestBatchContext(t *testing.T) {
|
||||||
b, ctx := New(context.Background())
|
b, ctx := New(context.Background())
|
||||||
|
|
||||||
b.Go("error", func() (interface{}, error) {
|
b.Go("error", func() (any, error) {
|
||||||
time.Sleep(time.Millisecond * 100)
|
time.Sleep(time.Millisecond * 100)
|
||||||
return nil, errors.New("test error")
|
return nil, errors.New("test error")
|
||||||
})
|
})
|
||||||
|
|
||||||
b.Go("ctx", func() (interface{}, error) {
|
b.Go("ctx", func() (any, error) {
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
return nil, ctx.Err()
|
return nil, ctx.Err()
|
||||||
})
|
})
|
||||||
|
|
10
common/cache/cache.go
vendored
10
common/cache/cache.go
vendored
|
@ -18,11 +18,11 @@ type cache struct {
|
||||||
|
|
||||||
type element struct {
|
type element struct {
|
||||||
Expired time.Time
|
Expired time.Time
|
||||||
Payload interface{}
|
Payload any
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put element in Cache with its ttl
|
// Put element in Cache with its ttl
|
||||||
func (c *cache) Put(key interface{}, payload interface{}, ttl time.Duration) {
|
func (c *cache) Put(key any, payload any, ttl time.Duration) {
|
||||||
c.mapping.Store(key, &element{
|
c.mapping.Store(key, &element{
|
||||||
Payload: payload,
|
Payload: payload,
|
||||||
Expired: time.Now().Add(ttl),
|
Expired: time.Now().Add(ttl),
|
||||||
|
@ -30,7 +30,7 @@ func (c *cache) Put(key interface{}, payload interface{}, ttl time.Duration) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get element in Cache, and drop when it expired
|
// Get element in Cache, and drop when it expired
|
||||||
func (c *cache) Get(key interface{}) interface{} {
|
func (c *cache) Get(key any) any {
|
||||||
item, exist := c.mapping.Load(key)
|
item, exist := c.mapping.Load(key)
|
||||||
if !exist {
|
if !exist {
|
||||||
return nil
|
return nil
|
||||||
|
@ -45,7 +45,7 @@ func (c *cache) Get(key interface{}) interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWithExpire element in Cache with Expire Time
|
// GetWithExpire element in Cache with Expire Time
|
||||||
func (c *cache) GetWithExpire(key interface{}) (payload interface{}, expired time.Time) {
|
func (c *cache) GetWithExpire(key any) (payload any, expired time.Time) {
|
||||||
item, exist := c.mapping.Load(key)
|
item, exist := c.mapping.Load(key)
|
||||||
if !exist {
|
if !exist {
|
||||||
return
|
return
|
||||||
|
@ -60,7 +60,7 @@ func (c *cache) GetWithExpire(key interface{}) (payload interface{}, expired tim
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) cleanup() {
|
func (c *cache) cleanup() {
|
||||||
c.mapping.Range(func(k, v interface{}) bool {
|
c.mapping.Range(func(k, v any) bool {
|
||||||
key := k.(string)
|
key := k.(string)
|
||||||
elm := v.(*element)
|
elm := v.(*element)
|
||||||
if time.Since(elm.Expired) > 0 {
|
if time.Since(elm.Expired) > 0 {
|
||||||
|
|
34
common/cache/lrucache.go
vendored
34
common/cache/lrucache.go
vendored
|
@ -12,7 +12,7 @@ import (
|
||||||
type Option func(*LruCache)
|
type Option func(*LruCache)
|
||||||
|
|
||||||
// EvictCallback is used to get a callback when a cache entry is evicted
|
// EvictCallback is used to get a callback when a cache entry is evicted
|
||||||
type EvictCallback = func(key interface{}, value interface{})
|
type EvictCallback = func(key any, value any)
|
||||||
|
|
||||||
// WithEvict set the evict callback
|
// WithEvict set the evict callback
|
||||||
func WithEvict(cb EvictCallback) Option {
|
func WithEvict(cb EvictCallback) Option {
|
||||||
|
@ -57,7 +57,7 @@ type LruCache struct {
|
||||||
maxAge int64
|
maxAge int64
|
||||||
maxSize int
|
maxSize int
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
cache map[interface{}]*list.Element
|
cache map[any]*list.Element
|
||||||
lru *list.List // Front is least-recent
|
lru *list.List // Front is least-recent
|
||||||
updateAgeOnGet bool
|
updateAgeOnGet bool
|
||||||
staleReturn bool
|
staleReturn bool
|
||||||
|
@ -68,7 +68,7 @@ type LruCache struct {
|
||||||
func NewLRUCache(options ...Option) *LruCache {
|
func NewLRUCache(options ...Option) *LruCache {
|
||||||
lc := &LruCache{
|
lc := &LruCache{
|
||||||
lru: list.New(),
|
lru: list.New(),
|
||||||
cache: make(map[interface{}]*list.Element),
|
cache: make(map[any]*list.Element),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
|
@ -78,9 +78,9 @@ func NewLRUCache(options ...Option) *LruCache {
|
||||||
return lc
|
return lc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the interface{} representation of a cached response and a bool
|
// Get returns the any representation of a cached response and a bool
|
||||||
// set to true if the key was found.
|
// set to true if the key was found.
|
||||||
func (c *LruCache) Get(key interface{}) (interface{}, bool) {
|
func (c *LruCache) Get(key any) (any, bool) {
|
||||||
entry := c.get(key)
|
entry := c.get(key)
|
||||||
if entry == nil {
|
if entry == nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
|
@ -90,11 +90,11 @@ func (c *LruCache) Get(key interface{}) (interface{}, bool) {
|
||||||
return value, true
|
return value, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWithExpire returns the interface{} representation of a cached response,
|
// GetWithExpire returns the any representation of a cached response,
|
||||||
// a time.Time Give expected expires,
|
// a time.Time Give expected expires,
|
||||||
// and a bool set to true if the key was found.
|
// and a bool set to true if the key was found.
|
||||||
// This method will NOT check the maxAge of element and will NOT update the expires.
|
// This method will NOT check the maxAge of element and will NOT update the expires.
|
||||||
func (c *LruCache) GetWithExpire(key interface{}) (interface{}, time.Time, bool) {
|
func (c *LruCache) GetWithExpire(key any) (any, time.Time, bool) {
|
||||||
entry := c.get(key)
|
entry := c.get(key)
|
||||||
if entry == nil {
|
if entry == nil {
|
||||||
return nil, time.Time{}, false
|
return nil, time.Time{}, false
|
||||||
|
@ -104,7 +104,7 @@ func (c *LruCache) GetWithExpire(key interface{}) (interface{}, time.Time, bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exist returns if key exist in cache but not put item to the head of linked list
|
// Exist returns if key exist in cache but not put item to the head of linked list
|
||||||
func (c *LruCache) Exist(key interface{}) bool {
|
func (c *LruCache) Exist(key any) bool {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
|
|
||||||
|
@ -112,8 +112,8 @@ func (c *LruCache) Exist(key interface{}) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set stores the interface{} representation of a response for a given key.
|
// Set stores the any representation of a response for a given key.
|
||||||
func (c *LruCache) Set(key interface{}, value interface{}) {
|
func (c *LruCache) Set(key any, value any) {
|
||||||
expires := int64(0)
|
expires := int64(0)
|
||||||
if c.maxAge > 0 {
|
if c.maxAge > 0 {
|
||||||
expires = time.Now().Unix() + c.maxAge
|
expires = time.Now().Unix() + c.maxAge
|
||||||
|
@ -121,9 +121,9 @@ func (c *LruCache) Set(key interface{}, value interface{}) {
|
||||||
c.SetWithExpire(key, value, time.Unix(expires, 0))
|
c.SetWithExpire(key, value, time.Unix(expires, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetWithExpire stores the interface{} representation of a response for a given key and given expires.
|
// SetWithExpire stores the any representation of a response for a given key and given expires.
|
||||||
// The expires time will round to second.
|
// The expires time will round to second.
|
||||||
func (c *LruCache) SetWithExpire(key interface{}, value interface{}, expires time.Time) {
|
func (c *LruCache) SetWithExpire(key any, value any, expires time.Time) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ func (c *LruCache) CloneTo(n *LruCache) {
|
||||||
defer n.mu.Unlock()
|
defer n.mu.Unlock()
|
||||||
|
|
||||||
n.lru = list.New()
|
n.lru = list.New()
|
||||||
n.cache = make(map[interface{}]*list.Element)
|
n.cache = make(map[any]*list.Element)
|
||||||
|
|
||||||
for e := c.lru.Front(); e != nil; e = e.Next() {
|
for e := c.lru.Front(); e != nil; e = e.Next() {
|
||||||
elm := e.Value.(*entry)
|
elm := e.Value.(*entry)
|
||||||
|
@ -163,7 +163,7 @@ func (c *LruCache) CloneTo(n *LruCache) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *LruCache) get(key interface{}) *entry {
|
func (c *LruCache) get(key any) *entry {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ func (c *LruCache) get(key interface{}) *entry {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete removes the value associated with a key.
|
// Delete removes the value associated with a key.
|
||||||
func (c *LruCache) Delete(key interface{}) {
|
func (c *LruCache) Delete(key any) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
|
|
||||||
if le, ok := c.cache[key]; ok {
|
if le, ok := c.cache[key]; ok {
|
||||||
|
@ -217,7 +217,7 @@ func (c *LruCache) deleteElement(le *list.Element) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type entry struct {
|
type entry struct {
|
||||||
key interface{}
|
key any
|
||||||
value interface{}
|
value any
|
||||||
expires int64
|
expires int64
|
||||||
}
|
}
|
||||||
|
|
2
common/cache/lrucache_test.go
vendored
2
common/cache/lrucache_test.go
vendored
|
@ -126,7 +126,7 @@ func TestExist(t *testing.T) {
|
||||||
|
|
||||||
func TestEvict(t *testing.T) {
|
func TestEvict(t *testing.T) {
|
||||||
temp := 0
|
temp := 0
|
||||||
evict := func(key interface{}, value interface{}) {
|
evict := func(key any, value any) {
|
||||||
temp = key.(int) + value.(int)
|
temp = key.(int) + value.(int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
package observable
|
package observable
|
||||||
|
|
||||||
type Iterable <-chan interface{}
|
type Iterable <-chan any
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"go.uber.org/atomic"
|
"go.uber.org/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
func iterator(item []interface{}) chan interface{} {
|
func iterator(item []any) chan any {
|
||||||
ch := make(chan interface{})
|
ch := make(chan any)
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
for _, elm := range item {
|
for _, elm := range item {
|
||||||
|
@ -22,7 +22,7 @@ func iterator(item []interface{}) chan interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObservable(t *testing.T) {
|
func TestObservable(t *testing.T) {
|
||||||
iter := iterator([]interface{}{1, 2, 3, 4, 5})
|
iter := iterator([]any{1, 2, 3, 4, 5})
|
||||||
src := NewObservable(iter)
|
src := NewObservable(iter)
|
||||||
data, err := src.Subscribe()
|
data, err := src.Subscribe()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
@ -34,7 +34,7 @@ func TestObservable(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObservable_MultiSubscribe(t *testing.T) {
|
func TestObservable_MultiSubscribe(t *testing.T) {
|
||||||
iter := iterator([]interface{}{1, 2, 3, 4, 5})
|
iter := iterator([]any{1, 2, 3, 4, 5})
|
||||||
src := NewObservable(iter)
|
src := NewObservable(iter)
|
||||||
ch1, _ := src.Subscribe()
|
ch1, _ := src.Subscribe()
|
||||||
ch2, _ := src.Subscribe()
|
ch2, _ := src.Subscribe()
|
||||||
|
@ -42,7 +42,7 @@ func TestObservable_MultiSubscribe(t *testing.T) {
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
waitCh := func(ch <-chan interface{}) {
|
waitCh := func(ch <-chan any) {
|
||||||
for range ch {
|
for range ch {
|
||||||
count.Inc()
|
count.Inc()
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ func TestObservable_MultiSubscribe(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObservable_UnSubscribe(t *testing.T) {
|
func TestObservable_UnSubscribe(t *testing.T) {
|
||||||
iter := iterator([]interface{}{1, 2, 3, 4, 5})
|
iter := iterator([]any{1, 2, 3, 4, 5})
|
||||||
src := NewObservable(iter)
|
src := NewObservable(iter)
|
||||||
data, err := src.Subscribe()
|
data, err := src.Subscribe()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
@ -65,7 +65,7 @@ func TestObservable_UnSubscribe(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObservable_SubscribeClosedSource(t *testing.T) {
|
func TestObservable_SubscribeClosedSource(t *testing.T) {
|
||||||
iter := iterator([]interface{}{1})
|
iter := iterator([]any{1})
|
||||||
src := NewObservable(iter)
|
src := NewObservable(iter)
|
||||||
data, _ := src.Subscribe()
|
data, _ := src.Subscribe()
|
||||||
<-data
|
<-data
|
||||||
|
@ -75,14 +75,14 @@ func TestObservable_SubscribeClosedSource(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObservable_UnSubscribeWithNotExistSubscription(t *testing.T) {
|
func TestObservable_UnSubscribeWithNotExistSubscription(t *testing.T) {
|
||||||
sub := Subscription(make(chan interface{}))
|
sub := Subscription(make(chan any))
|
||||||
iter := iterator([]interface{}{1})
|
iter := iterator([]any{1})
|
||||||
src := NewObservable(iter)
|
src := NewObservable(iter)
|
||||||
src.UnSubscribe(sub)
|
src.UnSubscribe(sub)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObservable_SubscribeGoroutineLeak(t *testing.T) {
|
func TestObservable_SubscribeGoroutineLeak(t *testing.T) {
|
||||||
iter := iterator([]interface{}{1, 2, 3, 4, 5})
|
iter := iterator([]any{1, 2, 3, 4, 5})
|
||||||
src := NewObservable(iter)
|
src := NewObservable(iter)
|
||||||
max := 100
|
max := 100
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ func TestObservable_SubscribeGoroutineLeak(t *testing.T) {
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(max)
|
wg.Add(max)
|
||||||
waitCh := func(ch <-chan interface{}) {
|
waitCh := func(ch <-chan any) {
|
||||||
for range ch {
|
for range ch {
|
||||||
}
|
}
|
||||||
wg.Done()
|
wg.Done()
|
||||||
|
@ -115,7 +115,7 @@ func TestObservable_SubscribeGoroutineLeak(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Benchmark_Observable_1000(b *testing.B) {
|
func Benchmark_Observable_1000(b *testing.B) {
|
||||||
ch := make(chan interface{})
|
ch := make(chan any)
|
||||||
o := NewObservable(ch)
|
o := NewObservable(ch)
|
||||||
num := 1000
|
num := 1000
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,14 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Subscription <-chan interface{}
|
type Subscription <-chan any
|
||||||
|
|
||||||
type Subscriber struct {
|
type Subscriber struct {
|
||||||
buffer chan interface{}
|
buffer chan any
|
||||||
once sync.Once
|
once sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Subscriber) Emit(item interface{}) {
|
func (s *Subscriber) Emit(item any) {
|
||||||
s.buffer <- item
|
s.buffer <- item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ func (s *Subscriber) Close() {
|
||||||
|
|
||||||
func newSubscriber() *Subscriber {
|
func newSubscriber() *Subscriber {
|
||||||
sub := &Subscriber{
|
sub := &Subscriber{
|
||||||
buffer: make(chan interface{}, 200),
|
buffer: make(chan any, 200),
|
||||||
}
|
}
|
||||||
return sub
|
return sub
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ type Picker struct {
|
||||||
|
|
||||||
once sync.Once
|
once sync.Once
|
||||||
errOnce sync.Once
|
errOnce sync.Once
|
||||||
result interface{}
|
result any
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ func WithTimeout(ctx context.Context, timeout time.Duration) (*Picker, context.C
|
||||||
|
|
||||||
// Wait blocks until all function calls from the Go method have returned,
|
// Wait blocks until all function calls from the Go method have returned,
|
||||||
// then returns the first nil error result (if any) from them.
|
// then returns the first nil error result (if any) from them.
|
||||||
func (p *Picker) Wait() interface{} {
|
func (p *Picker) Wait() any {
|
||||||
p.wg.Wait()
|
p.wg.Wait()
|
||||||
if p.cancel != nil {
|
if p.cancel != nil {
|
||||||
p.cancel()
|
p.cancel()
|
||||||
|
@ -58,7 +58,7 @@ func (p *Picker) Error() error {
|
||||||
|
|
||||||
// Go calls the given function in a new goroutine.
|
// Go calls the given function in a new goroutine.
|
||||||
// The first call to return a nil error cancels the group; its result will be returned by Wait.
|
// The first call to return a nil error cancels the group; its result will be returned by Wait.
|
||||||
func (p *Picker) Go(f func() (interface{}, error)) {
|
func (p *Picker) Go(f func() (any, error)) {
|
||||||
p.wg.Add(1)
|
p.wg.Add(1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func sleepAndSend(ctx context.Context, delay int, input interface{}) func() (interface{}, error) {
|
func sleepAndSend(ctx context.Context, delay int, input any) func() (any, error) {
|
||||||
return func() (interface{}, error) {
|
return func() (any, error) {
|
||||||
timer := time.NewTimer(time.Millisecond * time.Duration(delay))
|
timer := time.NewTimer(time.Millisecond * time.Duration(delay))
|
||||||
select {
|
select {
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
|
|
|
@ -23,7 +23,7 @@ func NewAllocator() *Allocator {
|
||||||
alloc.buffers = make([]sync.Pool, 17) // 1B -> 64K
|
alloc.buffers = make([]sync.Pool, 17) // 1B -> 64K
|
||||||
for k := range alloc.buffers {
|
for k := range alloc.buffers {
|
||||||
i := k
|
i := k
|
||||||
alloc.buffers[k].New = func() interface{} {
|
alloc.buffers[k].New = func() any {
|
||||||
return make([]byte, 1<<uint32(i))
|
return make([]byte, 1<<uint32(i))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var bufferPool = sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}
|
var bufferPool = sync.Pool{New: func() any { return &bytes.Buffer{} }}
|
||||||
|
|
||||||
func GetBuffer() *bytes.Buffer {
|
func GetBuffer() *bytes.Buffer {
|
||||||
return bufferPool.Get().(*bytes.Buffer)
|
return bufferPool.Get().(*bytes.Buffer)
|
||||||
|
|
|
@ -6,12 +6,12 @@ import (
|
||||||
|
|
||||||
// Queue is a simple concurrent safe queue
|
// Queue is a simple concurrent safe queue
|
||||||
type Queue struct {
|
type Queue struct {
|
||||||
items []interface{}
|
items []any
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put add the item to the queue.
|
// Put add the item to the queue.
|
||||||
func (q *Queue) Put(items ...interface{}) {
|
func (q *Queue) Put(items ...any) {
|
||||||
if len(items) == 0 {
|
if len(items) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ func (q *Queue) Put(items ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pop returns the head of items.
|
// Pop returns the head of items.
|
||||||
func (q *Queue) Pop() interface{} {
|
func (q *Queue) Pop() any {
|
||||||
if len(q.items) == 0 {
|
if len(q.items) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ func (q *Queue) Pop() interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last returns the last of item.
|
// Last returns the last of item.
|
||||||
func (q *Queue) Last() interface{} {
|
func (q *Queue) Last() any {
|
||||||
if len(q.items) == 0 {
|
if len(q.items) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ func (q *Queue) Last() interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy get the copy of queue.
|
// Copy get the copy of queue.
|
||||||
func (q *Queue) Copy() []interface{} {
|
func (q *Queue) Copy() []any {
|
||||||
items := []interface{}{}
|
items := []any{}
|
||||||
q.lock.RLock()
|
q.lock.RLock()
|
||||||
items = append(items, q.items...)
|
items = append(items, q.items...)
|
||||||
q.lock.RUnlock()
|
q.lock.RUnlock()
|
||||||
|
@ -66,6 +66,6 @@ func (q *Queue) Len() int64 {
|
||||||
// New is a constructor for a new concurrent safe queue.
|
// New is a constructor for a new concurrent safe queue.
|
||||||
func New(hint int64) *Queue {
|
func New(hint int64) *Queue {
|
||||||
return &Queue{
|
return &Queue{
|
||||||
items: make([]interface{}, 0, hint),
|
items: make([]any, 0, hint),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
|
|
||||||
type call struct {
|
type call struct {
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
val interface{}
|
val any
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,13 +20,13 @@ type Single struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result struct {
|
type Result struct {
|
||||||
Val interface{}
|
Val any
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do single.Do likes sync.singleFlight
|
// Do single.Do likes sync.singleFlight
|
||||||
//lint:ignore ST1008 it likes sync.singleFlight
|
//lint:ignore ST1008 it likes sync.singleFlight
|
||||||
func (s *Single) Do(fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
|
func (s *Single) Do(fn func() (any, error)) (v any, err error, shared bool) {
|
||||||
s.mux.Lock()
|
s.mux.Lock()
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if now.Before(s.last.Add(s.wait)) {
|
if now.Before(s.last.Add(s.wait)) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ func TestBasic(t *testing.T) {
|
||||||
single := NewSingle(time.Millisecond * 30)
|
single := NewSingle(time.Millisecond * 30)
|
||||||
foo := 0
|
foo := 0
|
||||||
shardCount := atomic.NewInt32(0)
|
shardCount := atomic.NewInt32(0)
|
||||||
call := func() (interface{}, error) {
|
call := func() (any, error) {
|
||||||
foo++
|
foo++
|
||||||
time.Sleep(time.Millisecond * 5)
|
time.Sleep(time.Millisecond * 5)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -40,7 +40,7 @@ func TestBasic(t *testing.T) {
|
||||||
func TestTimer(t *testing.T) {
|
func TestTimer(t *testing.T) {
|
||||||
single := NewSingle(time.Millisecond * 30)
|
single := NewSingle(time.Millisecond * 30)
|
||||||
foo := 0
|
foo := 0
|
||||||
call := func() (interface{}, error) {
|
call := func() (any, error) {
|
||||||
foo++
|
foo++
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ func TestTimer(t *testing.T) {
|
||||||
func TestReset(t *testing.T) {
|
func TestReset(t *testing.T) {
|
||||||
single := NewSingle(time.Millisecond * 30)
|
single := NewSingle(time.Millisecond * 30)
|
||||||
foo := 0
|
foo := 0
|
||||||
call := func() (interface{}, error) {
|
call := func() (any, error) {
|
||||||
foo++
|
foo++
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build !linux
|
//go:build !linux
|
||||||
// +build !linux
|
|
||||||
|
|
||||||
package sockopt
|
package sockopt
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ func NewDecoder(option Option) *Decoder {
|
||||||
return &Decoder{option: &option}
|
return &Decoder{option: &option}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode transform a map[string]interface{} to a struct
|
// Decode transform a map[string]any to a struct
|
||||||
func (d *Decoder) Decode(src map[string]interface{}, dst interface{}) error {
|
func (d *Decoder) Decode(src map[string]any, dst any) error {
|
||||||
if reflect.TypeOf(dst).Kind() != reflect.Ptr {
|
if reflect.TypeOf(dst).Kind() != reflect.Ptr {
|
||||||
return fmt.Errorf("Decode must recive a ptr struct")
|
return fmt.Errorf("Decode must recive a ptr struct")
|
||||||
}
|
}
|
||||||
|
@ -45,12 +45,8 @@ func (d *Decoder) Decode(src map[string]interface{}, dst interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
tag := field.Tag.Get(d.option.TagName)
|
tag := field.Tag.Get(d.option.TagName)
|
||||||
str := strings.SplitN(tag, ",", 2)
|
key, omitKey, found := strings.Cut(tag, ",")
|
||||||
key := str[0]
|
omitempty := found && omitKey == "omitempty"
|
||||||
omitempty := false
|
|
||||||
if len(str) > 1 {
|
|
||||||
omitempty = str[1] == "omitempty"
|
|
||||||
}
|
|
||||||
|
|
||||||
value, ok := src[key]
|
value, ok := src[key]
|
||||||
if !ok || value == nil {
|
if !ok || value == nil {
|
||||||
|
@ -68,7 +64,7 @@ func (d *Decoder) Decode(src map[string]interface{}, dst interface{}) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decode(name string, data any, val reflect.Value) error {
|
||||||
switch val.Kind() {
|
switch val.Kind() {
|
||||||
case reflect.Int:
|
case reflect.Int:
|
||||||
return d.decodeInt(name, data, val)
|
return d.decodeInt(name, data, val)
|
||||||
|
@ -89,7 +85,7 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) (err error) {
|
func (d *Decoder) decodeInt(name string, data any, val reflect.Value) (err error) {
|
||||||
dataVal := reflect.ValueOf(data)
|
dataVal := reflect.ValueOf(data)
|
||||||
kind := dataVal.Kind()
|
kind := dataVal.Kind()
|
||||||
switch {
|
switch {
|
||||||
|
@ -112,7 +108,7 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) (e
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) (err error) {
|
func (d *Decoder) decodeString(name string, data any, val reflect.Value) (err error) {
|
||||||
dataVal := reflect.ValueOf(data)
|
dataVal := reflect.ValueOf(data)
|
||||||
kind := dataVal.Kind()
|
kind := dataVal.Kind()
|
||||||
switch {
|
switch {
|
||||||
|
@ -129,7 +125,7 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) (err error) {
|
func (d *Decoder) decodeBool(name string, data any, val reflect.Value) (err error) {
|
||||||
dataVal := reflect.ValueOf(data)
|
dataVal := reflect.ValueOf(data)
|
||||||
kind := dataVal.Kind()
|
kind := dataVal.Kind()
|
||||||
switch {
|
switch {
|
||||||
|
@ -146,7 +142,7 @@ func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) (
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decodeSlice(name string, data any, val reflect.Value) error {
|
||||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
||||||
valType := val.Type()
|
valType := val.Type()
|
||||||
valElemType := valType.Elem()
|
valElemType := valType.Elem()
|
||||||
|
@ -173,7 +169,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decodeMap(name string, data any, val reflect.Value) error {
|
||||||
valType := val.Type()
|
valType := val.Type()
|
||||||
valKeyType := valType.Key()
|
valKeyType := valType.Key()
|
||||||
valElemType := valType.Elem()
|
valElemType := valType.Elem()
|
||||||
|
@ -245,7 +241,7 @@ func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val refle
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decodeStruct(name string, data any, val reflect.Value) error {
|
||||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
||||||
|
|
||||||
// If the type of the value to write to and the data match directly,
|
// If the type of the value to write to and the data match directly,
|
||||||
|
@ -273,7 +269,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||||
}
|
}
|
||||||
|
|
||||||
dataValKeys := make(map[reflect.Value]struct{})
|
dataValKeys := make(map[reflect.Value]struct{})
|
||||||
dataValKeysUnused := make(map[interface{}]struct{})
|
dataValKeysUnused := make(map[any]struct{})
|
||||||
for _, dataValKey := range dataVal.MapKeys() {
|
for _, dataValKey := range dataVal.MapKeys() {
|
||||||
dataValKeys[dataValKey] = struct{}{}
|
dataValKeys[dataValKey] = struct{}{}
|
||||||
dataValKeysUnused[dataValKey.Interface()] = struct{}{}
|
dataValKeysUnused[dataValKey.Interface()] = struct{}{}
|
||||||
|
@ -398,7 +394,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) setInterface(name string, data interface{}, val reflect.Value) (err error) {
|
func (d *Decoder) setInterface(name string, data any, val reflect.Value) (err error) {
|
||||||
dataVal := reflect.ValueOf(data)
|
dataVal := reflect.ValueOf(data)
|
||||||
val.Set(dataVal)
|
val.Set(dataVal)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -27,7 +27,7 @@ type BazOptional struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStructure_Basic(t *testing.T) {
|
func TestStructure_Basic(t *testing.T) {
|
||||||
rawMap := map[string]interface{}{
|
rawMap := map[string]any{
|
||||||
"foo": 1,
|
"foo": 1,
|
||||||
"bar": "test",
|
"bar": "test",
|
||||||
"extra": false,
|
"extra": false,
|
||||||
|
@ -45,7 +45,7 @@ func TestStructure_Basic(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStructure_Slice(t *testing.T) {
|
func TestStructure_Slice(t *testing.T) {
|
||||||
rawMap := map[string]interface{}{
|
rawMap := map[string]any{
|
||||||
"foo": 1,
|
"foo": 1,
|
||||||
"bar": []string{"one", "two"},
|
"bar": []string{"one", "two"},
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ func TestStructure_Slice(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStructure_Optional(t *testing.T) {
|
func TestStructure_Optional(t *testing.T) {
|
||||||
rawMap := map[string]interface{}{
|
rawMap := map[string]any{
|
||||||
"foo": 1,
|
"foo": 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ func TestStructure_Optional(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStructure_MissingKey(t *testing.T) {
|
func TestStructure_MissingKey(t *testing.T) {
|
||||||
rawMap := map[string]interface{}{
|
rawMap := map[string]any{
|
||||||
"foo": 1,
|
"foo": 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,14 +87,14 @@ func TestStructure_MissingKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStructure_ParamError(t *testing.T) {
|
func TestStructure_ParamError(t *testing.T) {
|
||||||
rawMap := map[string]interface{}{}
|
rawMap := map[string]any{}
|
||||||
s := Baz{}
|
s := Baz{}
|
||||||
err := decoder.Decode(rawMap, s)
|
err := decoder.Decode(rawMap, s)
|
||||||
assert.NotNilf(t, err, "should throw error: %#v", s)
|
assert.NotNilf(t, err, "should throw error: %#v", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStructure_SliceTypeError(t *testing.T) {
|
func TestStructure_SliceTypeError(t *testing.T) {
|
||||||
rawMap := map[string]interface{}{
|
rawMap := map[string]any{
|
||||||
"foo": 1,
|
"foo": 1,
|
||||||
"bar": []int{1, 2},
|
"bar": []int{1, 2},
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ func TestStructure_SliceTypeError(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStructure_WeakType(t *testing.T) {
|
func TestStructure_WeakType(t *testing.T) {
|
||||||
rawMap := map[string]interface{}{
|
rawMap := map[string]any{
|
||||||
"foo": "1",
|
"foo": "1",
|
||||||
"bar": []int{1},
|
"bar": []int{1},
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ func TestStructure_WeakType(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStructure_Nest(t *testing.T) {
|
func TestStructure_Nest(t *testing.T) {
|
||||||
rawMap := map[string]interface{}{
|
rawMap := map[string]any{
|
||||||
"foo": 1,
|
"foo": 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ func NewAuthenticator(users []AuthUser) Authenticator {
|
||||||
au.storage.Store(user.User, user.Pass)
|
au.storage.Store(user.User, user.Pass)
|
||||||
}
|
}
|
||||||
usernames := make([]string, 0, len(users))
|
usernames := make([]string, 0, len(users))
|
||||||
au.storage.Range(func(key, value interface{}) bool {
|
au.storage.Range(func(key, value any) bool {
|
||||||
usernames = append(usernames, key.(string))
|
usernames = append(usernames, key.(string))
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build !linux && !darwin
|
//go:build !linux && !darwin
|
||||||
// +build !linux,!darwin
|
|
||||||
|
|
||||||
package dialer
|
package dialer
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build linux
|
//go:build linux
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package dialer
|
package dialer
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build !linux
|
//go:build !linux
|
||||||
// +build !linux
|
|
||||||
|
|
||||||
package dialer
|
package dialer
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows
|
//go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows
|
||||||
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
|
|
||||||
|
|
||||||
package dialer
|
package dialer
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package dialer
|
package dialer
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ var (
|
||||||
var interfaces = singledo.NewSingle(time.Second * 20)
|
var interfaces = singledo.NewSingle(time.Second * 20)
|
||||||
|
|
||||||
func ResolveInterface(name string) (*Interface, error) {
|
func ResolveInterface(name string) (*Interface, error) {
|
||||||
value, err, _ := interfaces.Do(func() (interface{}, error) {
|
value, err, _ := interfaces.Do(func() (any, error) {
|
||||||
ifaces, err := net.Interfaces()
|
ifaces, err := net.Interfaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -6,17 +6,17 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Factory = func(context.Context) (interface{}, error)
|
type Factory = func(context.Context) (any, error)
|
||||||
|
|
||||||
type entry struct {
|
type entry struct {
|
||||||
elm interface{}
|
elm any
|
||||||
time time.Time
|
time time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(*pool)
|
type Option func(*pool)
|
||||||
|
|
||||||
// WithEvict set the evict callback
|
// WithEvict set the evict callback
|
||||||
func WithEvict(cb func(interface{})) Option {
|
func WithEvict(cb func(any)) Option {
|
||||||
return func(p *pool) {
|
return func(p *pool) {
|
||||||
p.evict = cb
|
p.evict = cb
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ func WithAge(maxAge int64) Option {
|
||||||
// WithSize defined max size of Pool
|
// WithSize defined max size of Pool
|
||||||
func WithSize(maxSize int) Option {
|
func WithSize(maxSize int) Option {
|
||||||
return func(p *pool) {
|
return func(p *pool) {
|
||||||
p.ch = make(chan interface{}, maxSize)
|
p.ch = make(chan any, maxSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,13 +42,13 @@ type Pool struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type pool struct {
|
type pool struct {
|
||||||
ch chan interface{}
|
ch chan any
|
||||||
factory Factory
|
factory Factory
|
||||||
evict func(interface{})
|
evict func(any)
|
||||||
maxAge int64
|
maxAge int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pool) GetContext(ctx context.Context) (interface{}, error) {
|
func (p *pool) GetContext(ctx context.Context) (any, error) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@ -68,11 +68,11 @@ func (p *pool) GetContext(ctx context.Context) (interface{}, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pool) Get() (interface{}, error) {
|
func (p *pool) Get() (any, error) {
|
||||||
return p.GetContext(context.Background())
|
return p.GetContext(context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pool) Put(item interface{}) {
|
func (p *pool) Put(item any) {
|
||||||
e := &entry{
|
e := &entry{
|
||||||
elm: item,
|
elm: item,
|
||||||
time: time.Now(),
|
time: time.Now(),
|
||||||
|
@ -100,7 +100,7 @@ func recycle(p *Pool) {
|
||||||
|
|
||||||
func New(factory Factory, options ...Option) *Pool {
|
func New(factory Factory, options ...Option) *Pool {
|
||||||
p := &pool{
|
p := &pool{
|
||||||
ch: make(chan interface{}, 10),
|
ch: make(chan any, 10),
|
||||||
factory: factory,
|
factory: factory,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
func lg() Factory {
|
func lg() Factory {
|
||||||
initial := -1
|
initial := -1
|
||||||
return func(context.Context) (interface{}, error) {
|
return func(context.Context) (any, error) {
|
||||||
initial++
|
initial++
|
||||||
return initial, nil
|
return initial, nil
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ func TestPool_MaxSize(t *testing.T) {
|
||||||
size := 5
|
size := 5
|
||||||
pool := New(g, WithSize(size))
|
pool := New(g, WithSize(size))
|
||||||
|
|
||||||
items := []interface{}{}
|
items := []any{}
|
||||||
|
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
item, _ := pool.Get()
|
item, _ := pool.Get()
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
//go:build !darwin && !linux && !windows && (!freebsd || !amd64)
|
//go:build !darwin && !linux && !windows && (!freebsd || !amd64)
|
||||||
// +build !darwin
|
|
||||||
// +build !linux
|
|
||||||
// +build !windows
|
|
||||||
// +build !freebsd !amd64
|
|
||||||
|
|
||||||
package process
|
package process
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ func ValidAndSplitDomain(domain string) ([]string, bool) {
|
||||||
// 3. subdomain.*.example.com
|
// 3. subdomain.*.example.com
|
||||||
// 4. .example.com
|
// 4. .example.com
|
||||||
// 5. +.example.com
|
// 5. +.example.com
|
||||||
func (t *DomainTrie) Insert(domain string, data interface{}) error {
|
func (t *DomainTrie) Insert(domain string, data any) error {
|
||||||
parts, valid := ValidAndSplitDomain(domain)
|
parts, valid := ValidAndSplitDomain(domain)
|
||||||
if !valid {
|
if !valid {
|
||||||
return ErrInvalidDomain
|
return ErrInvalidDomain
|
||||||
|
@ -68,7 +68,7 @@ func (t *DomainTrie) Insert(domain string, data interface{}) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *DomainTrie) insert(parts []string, data interface{}) {
|
func (t *DomainTrie) insert(parts []string, data any) {
|
||||||
node := t.root
|
node := t.root
|
||||||
// reverse storage domain part to save space
|
// reverse storage domain part to save space
|
||||||
for i := len(parts) - 1; i >= 0; i-- {
|
for i := len(parts) - 1; i >= 0; i-- {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package trie
|
||||||
// Node is the trie's node
|
// Node is the trie's node
|
||||||
type Node struct {
|
type Node struct {
|
||||||
children map[string]*Node
|
children map[string]*Node
|
||||||
Data interface{}
|
Data any
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) getChild(s string) *Node {
|
func (n *Node) getChild(s string) *Node {
|
||||||
|
@ -18,7 +18,7 @@ func (n *Node) addChild(s string, child *Node) {
|
||||||
n.children[s] = child
|
n.children[s] = child
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNode(data interface{}) *Node {
|
func newNode(data any) *Node {
|
||||||
return &Node{
|
return &Node{
|
||||||
Data: data,
|
Data: data,
|
||||||
children: map[string]*Node{},
|
children: map[string]*Node{},
|
||||||
|
|
|
@ -186,8 +186,8 @@ type RawConfig struct {
|
||||||
Tun Tun `yaml:"tun"`
|
Tun Tun `yaml:"tun"`
|
||||||
Experimental Experimental `yaml:"experimental"`
|
Experimental Experimental `yaml:"experimental"`
|
||||||
Profile Profile `yaml:"profile"`
|
Profile Profile `yaml:"profile"`
|
||||||
Proxy []map[string]interface{} `yaml:"proxies"`
|
Proxy []map[string]any `yaml:"proxies"`
|
||||||
ProxyGroup []map[string]interface{} `yaml:"proxy-groups"`
|
ProxyGroup []map[string]any
|
||||||
Rule []string `yaml:"rules"`
|
Rule []string `yaml:"rules"`
|
||||||
Script Script `yaml:"script"`
|
Script Script `yaml:"script"`
|
||||||
}
|
}
|
||||||
|
@ -216,8 +216,8 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
|
||||||
LogLevel: log.INFO,
|
LogLevel: log.INFO,
|
||||||
Hosts: map[string]string{},
|
Hosts: map[string]string{},
|
||||||
Rule: []string{},
|
Rule: []string{},
|
||||||
Proxy: []map[string]interface{}{},
|
Proxy: []map[string]any{},
|
||||||
ProxyGroup: []map[string]interface{}{},
|
ProxyGroup: []map[string]any{},
|
||||||
Tun: Tun{
|
Tun: Tun{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
Stack: "gvisor",
|
Stack: "gvisor",
|
||||||
|
@ -432,7 +432,19 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[
|
||||||
proxies[groupName] = adapter.NewProxy(group)
|
proxies[groupName] = adapter.NewProxy(group)
|
||||||
}
|
}
|
||||||
|
|
||||||
var ps []C.Proxy
|
// initial compatible provider
|
||||||
|
for _, pd := range providersMap {
|
||||||
|
if pd.VehicleType() != providerTypes.Compatible {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infoln("Start initial compatible provider %s", pd.Name())
|
||||||
|
if err := pd.Initial(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ps := []C.Proxy{}
|
||||||
for _, v := range proxyList {
|
for _, v := range proxyList {
|
||||||
ps = append(ps, proxies[v])
|
ps = append(ps, proxies[v])
|
||||||
}
|
}
|
||||||
|
@ -597,7 +609,7 @@ func parseHosts(cfg *RawConfig) (*trie.DomainTrie, error) {
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return nil, fmt.Errorf("%s is not a valid IP", ipStr)
|
return nil, fmt.Errorf("%s is not a valid IP", ipStr)
|
||||||
}
|
}
|
||||||
_ = tree.Insert(domain, ip)
|
tree.Insert(domain, ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,7 +634,7 @@ func hostWithDefaultPort(host string, defPort string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseNameServer(servers []string) ([]dns.NameServer, error) {
|
func parseNameServer(servers []string) ([]dns.NameServer, error) {
|
||||||
var nameservers []dns.NameServer
|
nameservers := []dns.NameServer{}
|
||||||
|
|
||||||
for idx, server := range servers {
|
for idx, server := range servers {
|
||||||
// parse without scheme .e.g 8.8.8.8:53
|
// parse without scheme .e.g 8.8.8.8:53
|
||||||
|
@ -693,7 +705,7 @@ func parseNameServerPolicy(nsPolicy map[string]string) (map[string]dns.NameServe
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFallbackIPCIDR(ips []string) ([]*net.IPNet, error) {
|
func parseFallbackIPCIDR(ips []string) ([]*net.IPNet, error) {
|
||||||
var ipNets []*net.IPNet
|
ipNets := []*net.IPNet{}
|
||||||
|
|
||||||
for idx, ip := range ips {
|
for idx, ip := range ips {
|
||||||
_, ipnet, err := net.ParseCIDR(ip)
|
_, ipnet, err := net.ParseCIDR(ip)
|
||||||
|
@ -795,7 +807,7 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie, rules []C.Rule) (*DNS,
|
||||||
if len(cfg.FakeIPFilter) != 0 {
|
if len(cfg.FakeIPFilter) != 0 {
|
||||||
host = trie.New()
|
host = trie.New()
|
||||||
for _, domain := range cfg.FakeIPFilter {
|
for _, domain := range cfg.FakeIPFilter {
|
||||||
_ = host.Insert(domain, true)
|
host.Insert(domain, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,11 +858,10 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie, rules []C.Rule) (*DNS,
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAuthentication(rawRecords []string) []auth.AuthUser {
|
func parseAuthentication(rawRecords []string) []auth.AuthUser {
|
||||||
users := make([]auth.AuthUser, 0)
|
users := []auth.AuthUser{}
|
||||||
for _, line := range rawRecords {
|
for _, line := range rawRecords {
|
||||||
userData := strings.SplitN(line, ":", 2)
|
if user, pass, found := strings.Cut(line, ":"); found {
|
||||||
if len(userData) == 2 {
|
users = append(users, auth.AuthUser{User: user, Pass: pass})
|
||||||
users = append(users, auth.AuthUser{User: userData[0], Pass: userData[1]})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return users
|
return users
|
||||||
|
|
|
@ -18,13 +18,13 @@ func trimArr(arr []string) (r []string) {
|
||||||
// Check if ProxyGroups form DAG(Directed Acyclic Graph), and sort all ProxyGroups by dependency order.
|
// Check if ProxyGroups form DAG(Directed Acyclic Graph), and sort all ProxyGroups by dependency order.
|
||||||
// Meanwhile, record the original index in the config file.
|
// Meanwhile, record the original index in the config file.
|
||||||
// If loop is detected, return an error with location of loop.
|
// If loop is detected, return an error with location of loop.
|
||||||
func proxyGroupsDagSort(groupsConfig []map[string]interface{}) error {
|
func proxyGroupsDagSort(groupsConfig []map[string]any) error {
|
||||||
type graphNode struct {
|
type graphNode struct {
|
||||||
indegree int
|
indegree int
|
||||||
// topological order
|
// topological order
|
||||||
topo int
|
topo int
|
||||||
// the original data in `groupsConfig`
|
// the original data in `groupsConfig`
|
||||||
data map[string]interface{}
|
data map[string]any
|
||||||
// `outdegree` and `from` are used in loop locating
|
// `outdegree` and `from` are used in loop locating
|
||||||
outdegree int
|
outdegree int
|
||||||
option *outboundgroup.GroupCommonOption
|
option *outboundgroup.GroupCommonOption
|
||||||
|
|
|
@ -21,7 +21,7 @@ const (
|
||||||
type DNSMode int
|
type DNSMode int
|
||||||
|
|
||||||
// UnmarshalYAML unserialize EnhancedMode with yaml
|
// UnmarshalYAML unserialize EnhancedMode with yaml
|
||||||
func (e *DNSMode) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
func (e *DNSMode) UnmarshalYAML(unmarshal func(any) error) error {
|
||||||
var tp string
|
var tp string
|
||||||
if err := unmarshal(&tp); err != nil {
|
if err := unmarshal(&tp); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -35,7 +35,7 @@ func (e *DNSMode) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalYAML serialize EnhancedMode with yaml
|
// MarshalYAML serialize EnhancedMode with yaml
|
||||||
func (e DNSMode) MarshalYAML() (interface{}, error) {
|
func (e DNSMode) MarshalYAML() (any, error) {
|
||||||
return e.String(), nil
|
return e.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ func (r *Resolver) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, e
|
||||||
func (r *Resolver) exchangeWithoutCache(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) {
|
func (r *Resolver) exchangeWithoutCache(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) {
|
||||||
q := m.Question[0]
|
q := m.Question[0]
|
||||||
|
|
||||||
ret, err, shared := r.group.Do(q.String(), func() (result interface{}, err error) {
|
ret, err, shared := r.group.Do(q.String(), func() (result any, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -154,7 +154,7 @@ func (r *Resolver) batchExchange(ctx context.Context, clients []dnsClient, m *D.
|
||||||
fast, ctx := picker.WithTimeout(ctx, resolver.DefaultDNSTimeout)
|
fast, ctx := picker.WithTimeout(ctx, resolver.DefaultDNSTimeout)
|
||||||
for _, client := range clients {
|
for _, client := range clients {
|
||||||
r := client
|
r := client
|
||||||
fast.Go(func() (interface{}, error) {
|
fast.Go(func() (any, error) {
|
||||||
m, err := r.ExchangeContext(ctx, m)
|
m, err := r.ExchangeContext(ctx, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -53,5 +53,4 @@ require (
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -117,10 +117,10 @@ func authentication(next http.Handler) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
header := r.Header.Get("Authorization")
|
header := r.Header.Get("Authorization")
|
||||||
text := strings.SplitN(header, " ", 2)
|
bearer, token, found := strings.Cut(header, " ")
|
||||||
|
|
||||||
hasInvalidHeader := text[0] != "Bearer"
|
hasInvalidHeader := bearer != "Bearer"
|
||||||
hasInvalidSecret := len(text) != 2 || text[1] != serverSecret
|
hasInvalidSecret := !found || token != serverSecret
|
||||||
if hasInvalidHeader || hasInvalidSecret {
|
if hasInvalidHeader || hasInvalidSecret {
|
||||||
render.Status(r, http.StatusUnauthorized)
|
render.Status(r, http.StatusUnauthorized)
|
||||||
render.JSON(w, r, ErrUnauthorized)
|
render.JSON(w, r, ErrUnauthorized)
|
||||||
|
|
|
@ -108,7 +108,7 @@ func authenticate(request *http.Request, cache *cache.Cache) *http.Response {
|
||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
var authed interface{}
|
var authed any
|
||||||
if authed = cache.Get(credential); authed == nil {
|
if authed = cache.Get(credential); authed == nil {
|
||||||
user, pass, err := decodeBasicProxyAuthorization(credential)
|
user, pass, err := decodeBasicProxyAuthorization(credential)
|
||||||
authed = err == nil && authenticator.Verify(user, pass)
|
authed = err == nil && authenticator.Verify(user, pass)
|
||||||
|
|
|
@ -65,10 +65,10 @@ func decodeBasicProxyAuthorization(credential string) (string, string, error) {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
login := strings.Split(string(plain), ":")
|
user, pass, found := strings.Cut(string(plain), ":")
|
||||||
if len(login) != 2 {
|
if !found {
|
||||||
return "", "", errors.New("invalid login")
|
return "", "", errors.New("invalid login")
|
||||||
}
|
}
|
||||||
|
|
||||||
return login[0], login[1], nil
|
return user, pass, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build linux && !386
|
//go:build linux && !386
|
||||||
// +build linux,!386
|
|
||||||
|
|
||||||
package redir
|
package redir
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build !darwin && !linux && !freebsd
|
//go:build !darwin && !linux && !freebsd
|
||||||
// +build !darwin,!linux,!freebsd
|
|
||||||
|
|
||||||
package redir
|
package redir
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build linux
|
//go:build linux
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package tproxy
|
package tproxy
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build !linux
|
//go:build !linux
|
||||||
// +build !linux
|
|
||||||
|
|
||||||
package tproxy
|
package tproxy
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build linux
|
//go:build linux
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package tproxy
|
package tproxy
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build !linux
|
//go:build !linux
|
||||||
// +build !linux
|
|
||||||
|
|
||||||
package tproxy
|
package tproxy
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ const (
|
||||||
type LogLevel int
|
type LogLevel int
|
||||||
|
|
||||||
// UnmarshalYAML unserialize LogLevel with yaml
|
// UnmarshalYAML unserialize LogLevel with yaml
|
||||||
func (l *LogLevel) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
func (l *LogLevel) UnmarshalYAML(unmarshal func(any) error) error {
|
||||||
var tp string
|
var tp string
|
||||||
unmarshal(&tp)
|
unmarshal(&tp)
|
||||||
level, exist := LogLevelMapping[tp]
|
level, exist := LogLevelMapping[tp]
|
||||||
|
@ -54,7 +54,7 @@ func (l LogLevel) MarshalJSON() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalYAML serialize LogLevel with yaml
|
// MarshalYAML serialize LogLevel with yaml
|
||||||
func (l LogLevel) MarshalYAML() (interface{}, error) {
|
func (l LogLevel) MarshalYAML() (any, error) {
|
||||||
return l.String(), nil
|
return l.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
log/log.go
14
log/log.go
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logCh = make(chan interface{})
|
logCh = make(chan any)
|
||||||
source = observable.NewObservable(logCh)
|
source = observable.NewObservable(logCh)
|
||||||
level = INFO
|
level = INFO
|
||||||
)
|
)
|
||||||
|
@ -29,31 +29,31 @@ func (e *Event) Type() string {
|
||||||
return e.LogLevel.String()
|
return e.LogLevel.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Infoln(format string, v ...interface{}) {
|
func Infoln(format string, v ...any) {
|
||||||
event := newLog(INFO, format, v...)
|
event := newLog(INFO, format, v...)
|
||||||
logCh <- event
|
logCh <- event
|
||||||
print(event)
|
print(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Warnln(format string, v ...interface{}) {
|
func Warnln(format string, v ...any) {
|
||||||
event := newLog(WARNING, format, v...)
|
event := newLog(WARNING, format, v...)
|
||||||
logCh <- event
|
logCh <- event
|
||||||
print(event)
|
print(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Errorln(format string, v ...interface{}) {
|
func Errorln(format string, v ...any) {
|
||||||
event := newLog(ERROR, format, v...)
|
event := newLog(ERROR, format, v...)
|
||||||
logCh <- event
|
logCh <- event
|
||||||
print(event)
|
print(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Debugln(format string, v ...interface{}) {
|
func Debugln(format string, v ...any) {
|
||||||
event := newLog(DEBUG, format, v...)
|
event := newLog(DEBUG, format, v...)
|
||||||
logCh <- event
|
logCh <- event
|
||||||
print(event)
|
print(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Fatalln(format string, v ...interface{}) {
|
func Fatalln(format string, v ...any) {
|
||||||
log.Fatalf(format, v...)
|
log.Fatalf(format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ func print(data *Event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLog(logLevel LogLevel, format string, v ...interface{}) *Event {
|
func newLog(logLevel LogLevel, format string, v ...any) *Event {
|
||||||
return &Event{
|
return &Event{
|
||||||
LogLevel: logLevel,
|
LogLevel: logLevel,
|
||||||
Payload: fmt.Sprintf(format, v...),
|
Payload: fmt.Sprintf(format, v...),
|
||||||
|
|
2
main.go
2
main.go
|
@ -48,7 +48,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
_, _ = maxprocs.Set(maxprocs.Logger(func(string, ...interface{}) {}))
|
maxprocs.Set(maxprocs.Logger(func(string, ...any) {}))
|
||||||
if version {
|
if version {
|
||||||
fmt.Printf("Clash Meta %s %s %s with %s %s\n", C.Version, runtime.GOOS, runtime.GOARCH, runtime.Version(), C.BuildTime)
|
fmt.Printf("Clash Meta %s %s %s with %s %s\n", C.Version, runtime.GOOS, runtime.GOARCH, runtime.Version(), C.BuildTime)
|
||||||
return
|
return
|
||||||
|
|
35
test/go.mod
35
test/go.mod
|
@ -1,30 +1,33 @@
|
||||||
module clash-test
|
module clash-test
|
||||||
|
|
||||||
go 1.17
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Dreamacro/clash v1.7.2-0.20211108085948-bd2ea2b917aa
|
github.com/Dreamacro/clash v1.7.2-0.20211108085948-bd2ea2b917aa
|
||||||
github.com/docker/docker v20.10.12+incompatible
|
github.com/docker/docker v20.10.13+incompatible
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/miekg/dns v1.1.45
|
github.com/miekg/dns v1.1.47
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.1
|
||||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f
|
golang.org/x/net v0.0.0-20220225172249-27dd8689420f
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/Dreamacro/clash => ../
|
replace github.com/Dreamacro/clash => ../
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Dreamacro/go-shadowsocks2 v0.1.7 // indirect
|
github.com/Dreamacro/go-shadowsocks2 v0.1.7 // indirect
|
||||||
github.com/Microsoft/go-winio v0.5.1 // indirect
|
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||||
github.com/containerd/containerd v1.5.8 // indirect
|
github.com/containerd/containerd v1.6.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/docker/distribution v2.7.1+incompatible // indirect
|
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||||
github.com/docker/go-units v0.4.0 // indirect
|
github.com/docker/go-units v0.4.0 // indirect
|
||||||
github.com/gofrs/uuid v4.2.0+incompatible // indirect
|
github.com/gofrs/uuid v4.2.0+incompatible // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
github.com/google/btree v1.0.1 // indirect
|
github.com/google/btree v1.0.1 // indirect
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/insomniacslk/dhcp v0.0.0-20220119180841-3c283ff8b7dd // indirect
|
||||||
github.com/gorilla/websocket v1.4.2 // indirect
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489 // indirect
|
github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489 // indirect
|
||||||
github.com/kr328/tun2socket v0.0.0-20210412191540-3d56c47e2d99 // indirect
|
github.com/kr328/tun2socket v0.0.0-20210412191540-3d56c47e2d99 // indirect
|
||||||
|
@ -32,7 +35,7 @@ require (
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||||
github.com/oschwald/geoip2-golang v1.5.0 // indirect
|
github.com/oschwald/geoip2-golang v1.6.1 // indirect
|
||||||
github.com/oschwald/maxminddb-golang v1.8.0 // indirect
|
github.com/oschwald/maxminddb-golang v1.8.0 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
@ -42,16 +45,16 @@ require (
|
||||||
github.com/yaling888/go-lwip v0.0.0-20211103185822-c9d650538091 // indirect
|
github.com/yaling888/go-lwip v0.0.0-20211103185822-c9d650538091 // indirect
|
||||||
go.etcd.io/bbolt v1.3.6 // indirect
|
go.etcd.io/bbolt v1.3.6 // indirect
|
||||||
go.uber.org/atomic v1.9.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
|
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
|
||||||
golang.org/x/mod v0.4.2 // indirect
|
golang.org/x/mod v0.4.2 // indirect
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 // indirect
|
||||||
golang.org/x/text v0.3.6 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
|
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
|
||||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
|
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a // indirect
|
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
|
||||||
google.golang.org/grpc v1.43.0 // indirect
|
google.golang.org/grpc v1.45.0 // indirect
|
||||||
google.golang.org/protobuf v1.27.1 // indirect
|
google.golang.org/protobuf v1.27.1 // indirect
|
||||||
golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42 // indirect
|
golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42 // indirect
|
||||||
golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b // indirect
|
golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b // indirect
|
||||||
|
@ -61,6 +64,8 @@ require (
|
||||||
google.golang.org/grpc v1.42.0 // indirect
|
google.golang.org/grpc v1.42.0 // indirect
|
||||||
google.golang.org/protobuf v1.27.1 // indirect
|
google.golang.org/protobuf v1.27.1 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
|
gotest.tools/v3 v3.1.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||||
gvisor.dev/gvisor v0.0.0-20211104052249-2de3450f76d6 // indirect
|
gvisor.dev/gvisor v0.0.0-20211104052249-2de3450f76d6 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
@ -37,7 +37,7 @@ func TestClash_SnellObfsHTTP(t *testing.T) {
|
||||||
Server: localIP.String(),
|
Server: localIP.String(),
|
||||||
Port: 10002,
|
Port: 10002,
|
||||||
Psk: "password",
|
Psk: "password",
|
||||||
ObfsOpts: map[string]interface{}{
|
ObfsOpts: map[string]any{
|
||||||
"mode": "http",
|
"mode": "http",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -74,7 +74,7 @@ func TestClash_SnellObfsTLS(t *testing.T) {
|
||||||
Server: localIP.String(),
|
Server: localIP.String(),
|
||||||
Port: 10002,
|
Port: 10002,
|
||||||
Psk: "password",
|
Psk: "password",
|
||||||
ObfsOpts: map[string]interface{}{
|
ObfsOpts: map[string]any{
|
||||||
"mode": "tls",
|
"mode": "tls",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -181,7 +181,7 @@ func Benchmark_Snell(b *testing.B) {
|
||||||
Server: localIP.String(),
|
Server: localIP.String(),
|
||||||
Port: 10002,
|
Port: 10002,
|
||||||
Psk: "password",
|
Psk: "password",
|
||||||
ObfsOpts: map[string]interface{}{
|
ObfsOpts: map[string]any{
|
||||||
"mode": "http",
|
"mode": "http",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -76,7 +76,7 @@ func TestClash_ShadowsocksObfsHTTP(t *testing.T) {
|
||||||
Cipher: "chacha20-ietf-poly1305",
|
Cipher: "chacha20-ietf-poly1305",
|
||||||
UDP: true,
|
UDP: true,
|
||||||
Plugin: "obfs",
|
Plugin: "obfs",
|
||||||
PluginOpts: map[string]interface{}{
|
PluginOpts: map[string]any{
|
||||||
"mode": "http",
|
"mode": "http",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -118,7 +118,7 @@ func TestClash_ShadowsocksObfsTLS(t *testing.T) {
|
||||||
Cipher: "chacha20-ietf-poly1305",
|
Cipher: "chacha20-ietf-poly1305",
|
||||||
UDP: true,
|
UDP: true,
|
||||||
Plugin: "obfs",
|
Plugin: "obfs",
|
||||||
PluginOpts: map[string]interface{}{
|
PluginOpts: map[string]any{
|
||||||
"mode": "tls",
|
"mode": "tls",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -160,7 +160,7 @@ func TestClash_ShadowsocksV2RayPlugin(t *testing.T) {
|
||||||
Cipher: "chacha20-ietf-poly1305",
|
Cipher: "chacha20-ietf-poly1305",
|
||||||
UDP: true,
|
UDP: true,
|
||||||
Plugin: "v2ray-plugin",
|
Plugin: "v2ray-plugin",
|
||||||
PluginOpts: map[string]interface{}{
|
PluginOpts: map[string]any{
|
||||||
"mode": "websocket",
|
"mode": "websocket",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build !darwin
|
//go:build !darwin
|
||||||
// +build !darwin
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
|
@ -71,12 +71,12 @@ func (pc *PoolConn) Close() error {
|
||||||
|
|
||||||
func NewPool(factory func(context.Context) (*Snell, error)) *Pool {
|
func NewPool(factory func(context.Context) (*Snell, error)) *Pool {
|
||||||
p := pool.New(
|
p := pool.New(
|
||||||
func(ctx context.Context) (interface{}, error) {
|
func(ctx context.Context) (any, error) {
|
||||||
return factory(ctx)
|
return factory(ctx)
|
||||||
},
|
},
|
||||||
pool.WithAge(15000),
|
pool.WithAge(15000),
|
||||||
pool.WithSize(10),
|
pool.WithSize(10),
|
||||||
pool.WithEvict(func(item interface{}) {
|
pool.WithEvict(func(item any) {
|
||||||
item.(*Snell).Close()
|
item.(*Snell).Close()
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
|
@ -36,7 +36,7 @@ func (m *TunnelMode) UnmarshalJSON(data []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalYAML unserialize Mode with yaml
|
// UnmarshalYAML unserialize Mode with yaml
|
||||||
func (m *TunnelMode) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
func (m *TunnelMode) UnmarshalYAML(unmarshal func(any) error) error {
|
||||||
var tp string
|
var tp string
|
||||||
unmarshal(&tp)
|
unmarshal(&tp)
|
||||||
mode, exist := ModeMapping[strings.ToLower(tp)]
|
mode, exist := ModeMapping[strings.ToLower(tp)]
|
||||||
|
@ -53,7 +53,7 @@ func (m TunnelMode) MarshalJSON() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalYAML serialize TunnelMode with yaml
|
// MarshalYAML serialize TunnelMode with yaml
|
||||||
func (m TunnelMode) MarshalYAML() (interface{}, error) {
|
func (m TunnelMode) MarshalYAML() (any, error) {
|
||||||
return m.String(), nil
|
return m.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ func (m *Manager) Now() (up int64, down int64) {
|
||||||
|
|
||||||
func (m *Manager) Snapshot() *Snapshot {
|
func (m *Manager) Snapshot() *Snapshot {
|
||||||
connections := []tracker{}
|
connections := []tracker{}
|
||||||
m.connections.Range(func(key, value interface{}) bool {
|
m.connections.Range(func(key, value any) bool {
|
||||||
connections = append(connections, value.(tracker))
|
connections = append(connections, value.(tracker))
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue