mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-13 21:54:13 +08:00
don't remove outbounds if the a provider fails
This commit is contained in:
parent
22b79b297f
commit
2da163d59b
@ -64,10 +64,9 @@ func NewSubscription(ctx context.Context, router adapter.Router, logger log.Cont
|
|||||||
exclude *regexp.Regexp
|
exclude *regexp.Regexp
|
||||||
include *regexp.Regexp
|
include *regexp.Regexp
|
||||||
)
|
)
|
||||||
if p.Tag != "" {
|
// required for outbounds clean up
|
||||||
tag = p.Tag
|
if p.Tag == "" {
|
||||||
} else {
|
return nil, E.New("tag of provider [", i, "] is required")
|
||||||
tag = F.ToString(i)
|
|
||||||
}
|
}
|
||||||
if p.URL == "" {
|
if p.URL == "" {
|
||||||
return nil, E.New("missing URL for provider [", tag, "]")
|
return nil, E.New("missing URL for provider [", tag, "]")
|
||||||
@ -117,7 +116,7 @@ func NewSubscription(ctx context.Context, router adapter.Router, logger log.Cont
|
|||||||
|
|
||||||
// Start starts the service.
|
// Start starts the service.
|
||||||
func (s *Subscription) Start() error {
|
func (s *Subscription) Start() error {
|
||||||
go s.fetchLoop()
|
go s.refreshLoop()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +128,7 @@ func (s *Subscription) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Subscription) fetchLoop() {
|
func (s *Subscription) refreshLoop() {
|
||||||
ticker := time.NewTicker(s.interval)
|
ticker := time.NewTicker(s.interval)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
@ -146,16 +145,26 @@ L:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Subscription) refresh() {
|
func (s *Subscription) refresh() {
|
||||||
opts, err := s.fetch()
|
client, err := s.client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("fetch subscription: ", err)
|
s.logger.Error("client: ", err)
|
||||||
|
}
|
||||||
|
// outbounds before refresh
|
||||||
|
outbounds := s.router.Outbounds()
|
||||||
|
for _, provider := range s.providers {
|
||||||
|
opts, err := s.fetch(client, provider)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Warn("fetch provider [", provider.tag, "]: ", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s.logger.Info(len(opts), " links found from provider [", provider.tag, "]")
|
||||||
|
s.updateOutbounds(provider, opts, outbounds)
|
||||||
}
|
}
|
||||||
s.updateOutbounds(opts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Subscription) updateOutbounds(opts []*option.Outbound) {
|
func (s *Subscription) updateOutbounds(provider *subscriptionProvider, opts []*option.Outbound, outbounds []adapter.Outbound) {
|
||||||
outbounds := s.router.Outbounds()
|
|
||||||
knownOutbounds := make(map[string]struct{})
|
knownOutbounds := make(map[string]struct{})
|
||||||
|
removeCount := 0
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
tag := opt.Tag
|
tag := opt.Tag
|
||||||
knownOutbounds[tag] = struct{}{}
|
knownOutbounds[tag] = struct{}{}
|
||||||
@ -172,7 +181,7 @@ func (s *Subscription) updateOutbounds(opts []*option.Outbound) {
|
|||||||
s.logger.Info("created outbound [", tag, "]")
|
s.logger.Info("created outbound [", tag, "]")
|
||||||
}
|
}
|
||||||
// remove outbounds that are not in the latest list
|
// remove outbounds that are not in the latest list
|
||||||
tagPrefix := s.tag + "."
|
tagPrefix := s.tag + "." + provider.tag
|
||||||
for _, outbound := range outbounds {
|
for _, outbound := range outbounds {
|
||||||
tag := outbound.Tag()
|
tag := outbound.Tag()
|
||||||
if !strings.HasPrefix(tag, tagPrefix) {
|
if !strings.HasPrefix(tag, tagPrefix) {
|
||||||
@ -181,37 +190,27 @@ func (s *Subscription) updateOutbounds(opts []*option.Outbound) {
|
|||||||
if _, ok := knownOutbounds[tag]; ok {
|
if _, ok := knownOutbounds[tag]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
removeCount++
|
||||||
s.router.RemoveOutbound(tag)
|
s.router.RemoveOutbound(tag)
|
||||||
}
|
}
|
||||||
|
if removeCount > 0 {
|
||||||
|
s.logger.Info(removeCount, " outbounds removed for [", tagPrefix, "]")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Subscription) fetch() ([]*option.Outbound, error) {
|
func (s *Subscription) fetch(client *http.Client, provider *subscriptionProvider) ([]*option.Outbound, error) {
|
||||||
client, err := s.client()
|
opts := make([]*option.Outbound, 0)
|
||||||
|
links, err := s.fetchProvider(client, provider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
opts := make([]*option.Outbound, 0)
|
for _, link := range links {
|
||||||
for i, provider := range s.providers {
|
opt := link.Options()
|
||||||
var tag string
|
if !selectedByTag(opt.Tag, provider) {
|
||||||
if provider.tag != "" {
|
|
||||||
tag = provider.tag
|
|
||||||
} else {
|
|
||||||
tag = F.ToString(i)
|
|
||||||
}
|
|
||||||
links, err := s.fetchProvider(client, provider)
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Warn("fetch provider [", tag, "]: ", err)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
s.logger.Info(len(links), " links found from provider [", tag, "]")
|
s.applyOptions(opt, provider)
|
||||||
for _, link := range links {
|
opts = append(opts, opt)
|
||||||
opt := link.Options()
|
|
||||||
if !selectedByTag(opt.Tag, provider) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s.applyOptions(opt, provider)
|
|
||||||
opts = append(opts, opt)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return opts, nil
|
return opts, nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user