feat: local file type provider will auto update after modify

This commit is contained in:
wwqgtxx 2024-07-24 14:26:15 +08:00
parent 313493cc94
commit d6a1af23a7
2 changed files with 39 additions and 17 deletions

View File

@ -10,6 +10,7 @@ import (
types "github.com/metacubex/mihomo/constant/provider"
"github.com/metacubex/mihomo/log"
"github.com/sagernet/fswatch"
"github.com/samber/lo"
)
@ -30,6 +31,7 @@ type Fetcher[V any] struct {
parser Parser[V]
interval time.Duration
OnUpdate func(V)
watcher *fswatch.Watcher
}
func (f *Fetcher[V]) Name() string {
@ -113,7 +115,20 @@ func (f *Fetcher[V]) Initial() (V, error) {
f.hash = md5.Sum(buf)
// pull contents automatically
if f.interval > 0 {
if f.vehicle.Type() == types.File {
f.watcher, err = fswatch.NewWatcher(fswatch.Options{
Path: []string{f.vehicle.Path()},
Direct: true,
Callback: f.update,
})
if err != nil {
return lo.Empty[V](), err
}
err = f.watcher.Start()
if err != nil {
return lo.Empty[V](), err
}
} else if f.interval > 0 {
go f.pullLoop()
}
@ -155,6 +170,9 @@ func (f *Fetcher[V]) Destroy() error {
if f.interval > 0 {
f.done <- struct{}{}
}
if f.watcher != nil {
_ = f.watcher.Close()
}
return nil
}
@ -170,27 +188,31 @@ func (f *Fetcher[V]) pullLoop() {
select {
case <-timer.C:
timer.Reset(f.interval)
elm, same, err := f.Update()
if err != nil {
log.Errorln("[Provider] %s pull error: %s", f.Name(), err.Error())
continue
}
if same {
log.Debugln("[Provider] %s's content doesn't change", f.Name())
continue
}
log.Infoln("[Provider] %s's content update", f.Name())
if f.OnUpdate != nil {
f.OnUpdate(elm)
}
f.update(f.vehicle.Path())
case <-f.done:
return
}
}
}
func (f *Fetcher[V]) update(path string) {
elm, same, err := f.Update()
if err != nil {
log.Errorln("[Provider] %s pull error: %s", f.Name(), err.Error())
return
}
if same {
log.Debugln("[Provider] %s's content doesn't change", f.Name())
return
}
log.Infoln("[Provider] %s's content update", f.Name())
if f.OnUpdate != nil {
f.OnUpdate(elm)
}
}
func safeWrite(path string, buf []byte) error {
dir := filepath.Dir(path)

2
go.mod
View File

@ -35,6 +35,7 @@ require (
github.com/oschwald/maxminddb-golang v1.12.0
github.com/puzpuzpuz/xsync/v3 v3.2.0
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
github.com/sagernet/fswatch v0.1.1
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
github.com/sagernet/sing v0.5.0-alpha.13
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6
@ -93,7 +94,6 @@ require (
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
github.com/sagernet/fswatch v0.1.1 // indirect
github.com/sagernet/nftables v0.3.0-beta.4 // indirect
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect