diff --git a/adapter/provider/fetcher.go b/adapter/provider/fetcher.go index 4a7be8b1..297e82f7 100644 --- a/adapter/provider/fetcher.go +++ b/adapter/provider/fetcher.go @@ -21,6 +21,7 @@ type parser = func([]byte) (any, error) type fetcher struct { name string vehicle types.Vehicle + interval time.Duration updatedAt *time.Time ticker *time.Ticker done chan struct{} @@ -39,15 +40,17 @@ func (f *fetcher) VehicleType() types.VehicleType { func (f *fetcher) Initial() (any, error) { var ( - buf []byte - err error - isLocal bool + buf []byte + err error + isLocal bool + immediatelyUpdate bool ) if stat, fErr := os.Stat(f.vehicle.Path()); fErr == nil { buf, err = os.ReadFile(f.vehicle.Path()) modTime := stat.ModTime() f.updatedAt = &modTime isLocal = true + immediatelyUpdate = time.Since(modTime) > f.interval } else { buf, err = f.vehicle.Read() } @@ -86,7 +89,7 @@ func (f *fetcher) Initial() (any, error) { // pull proxies automatically if f.ticker != nil { - go f.pullLoop() + go f.pullLoop(immediatelyUpdate) } return proxies, nil @@ -130,25 +133,33 @@ func (f *fetcher) Destroy() error { return nil } -func (f *fetcher) pullLoop() { +func (f *fetcher) pullLoop(immediately bool) { + update := func() { + elm, same, err := f.Update() + if err != nil { + log.Warnln("[Provider] %s pull error: %s", f.Name(), err.Error()) + return + } + + if same { + log.Debugln("[Provider] %s's proxies doesn't change", f.Name()) + return + } + + log.Infoln("[Provider] %s's proxies update", f.Name()) + if f.onUpdate != nil { + f.onUpdate(elm) + } + } + + if immediately { + update() + } + for { select { case <-f.ticker.C: - elm, same, err := f.Update() - if err != nil { - log.Warnln("[Provider] %s pull error: %s", f.Name(), err.Error()) - continue - } - - if same { - log.Debugln("[Provider] %s's proxies doesn't change", f.Name()) - continue - } - - log.Infoln("[Provider] %s's proxies update", f.Name()) - if f.onUpdate != nil { - f.onUpdate(elm) - } + update() case <-f.done: f.ticker.Stop() return @@ -178,6 +189,7 @@ func newFetcher(name string, interval time.Duration, vehicle types.Vehicle, pars name: name, ticker: ticker, vehicle: vehicle, + interval: interval, parser: parser, done: make(chan struct{}, 1), onUpdate: onUpdate,