chore: auto update geo

This commit is contained in:
Larvan2 2024-05-19 17:30:39 +08:00 committed by wwqgtxx
parent e749c7e492
commit 4243a74284
3 changed files with 42 additions and 63 deletions

View File

@ -98,11 +98,13 @@ func updateGeoDatabases() error {
return nil return nil
} }
func UpdateGeoDatabases(updateNotification chan struct{}) error { var ErrGetDatabaseUpdateSkip = errors.New("GEO database is updating, skip")
func UpdateGeoDatabases() error {
log.Infoln("[GEO] Start updating GEO database") log.Infoln("[GEO] Start updating GEO database")
if UpdatingGeo.Load() { if UpdatingGeo.Load() {
return errors.New("GEO database is updating, skip") return ErrGetDatabaseUpdateSkip
} }
UpdatingGeo.Store(true) UpdatingGeo.Store(true)
@ -115,7 +117,6 @@ func UpdateGeoDatabases(updateNotification chan struct{}) error {
return err return err
} }
updateNotification <- struct{}{}
return nil return nil
} }
@ -136,17 +137,16 @@ func getUpdateTime() (err error, time time.Time) {
return nil, fileInfo.ModTime() return nil, fileInfo.ModTime()
} }
func RegisterGeoUpdater(updateNotification chan struct{}) { func RegisterGeoUpdater(onSuccess func()) {
if C.GeoUpdateInterval <= 0 { if C.GeoUpdateInterval <= 0 {
log.Errorln("[GEO] Invalid update interval: %d", C.GeoUpdateInterval) log.Errorln("[GEO] Invalid update interval: %d", C.GeoUpdateInterval)
return return
} }
ticker := time.NewTicker(time.Duration(C.GeoUpdateInterval) * time.Hour)
defer ticker.Stop()
log.Infoln("[GEO] update GEO database every %d hours", C.GeoUpdateInterval)
go func() { go func() {
ticker := time.NewTicker(time.Duration(C.GeoUpdateInterval) * time.Hour)
defer ticker.Stop()
err, lastUpdate := getUpdateTime() err, lastUpdate := getUpdateTime()
if err != nil { if err != nil {
log.Errorln("[GEO] Get GEO database update time error: %s", err.Error()) log.Errorln("[GEO] Get GEO database update time error: %s", err.Error())
@ -156,15 +156,20 @@ func RegisterGeoUpdater(updateNotification chan struct{}) {
log.Infoln("[GEO] last update time %s", lastUpdate) log.Infoln("[GEO] last update time %s", lastUpdate)
if lastUpdate.Add(time.Duration(C.GeoUpdateInterval) * time.Hour).Before(time.Now()) { if lastUpdate.Add(time.Duration(C.GeoUpdateInterval) * time.Hour).Before(time.Now()) {
log.Infoln("[GEO] Database has not been updated for %v, update now", time.Duration(C.GeoUpdateInterval)*time.Hour) log.Infoln("[GEO] Database has not been updated for %v, update now", time.Duration(C.GeoUpdateInterval)*time.Hour)
if err := UpdateGeoDatabases(updateNotification); err != nil { if err := UpdateGeoDatabases(); err != nil {
log.Errorln("[GEO] Failed to update GEO database: %s", err.Error()) log.Errorln("[GEO] Failed to update GEO database: %s", err.Error())
return return
} else {
onSuccess()
} }
} }
for range ticker.C { for range ticker.C {
if err := UpdateGeoDatabases(updateNotification); err != nil { log.Infoln("[GEO] updating database every %d hours", C.GeoUpdateInterval)
if err := UpdateGeoDatabases(); err != nil {
log.Errorln("[GEO] Failed to update GEO database: %s", err.Error()) log.Errorln("[GEO] Failed to update GEO database: %s", err.Error())
} else {
onSuccess()
} }
} }
}() }()

View File

@ -364,47 +364,25 @@ func updateConfigs(w http.ResponseWriter, r *http.Request) {
} }
func updateGeoDatabases(w http.ResponseWriter, r *http.Request) { func updateGeoDatabases(w http.ResponseWriter, r *http.Request) {
updateNotification := make(chan struct{}) err := updater.UpdateGeoDatabases()
errorChannel := make(chan error, 1) if err != nil {
done := make(chan struct{}) log.Errorln("[REST-API] update GEO databases failed: %v", err)
defer func() { render.Status(r, http.StatusInternalServerError)
close(updateNotification) render.JSON(w, r, newError(err.Error()))
close(errorChannel) return
}() }
go func() { cfg, err := executor.ParseWithPath(C.Path.Config())
defer close(done) if err != nil {
for { log.Errorln("[REST-API] update GEO databases failed: %v", err)
select { render.Status(r, http.StatusInternalServerError)
case <-updateNotification: render.JSON(w, r, newError("Error parsing configuration"))
cfg, err := executor.ParseWithPath(C.Path.Config()) return
if err != nil { }
log.Errorln("[REST-API] update GEO databases failed: %v", err)
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, newError("Error parsing configuration"))
return
}
log.Warnln("[REST-API] update GEO databases success, applying config") log.Warnln("[GEO] update GEO databases success, applying config")
executor.ApplyConfig(cfg, false)
return
case err := <-errorChannel:
log.Errorln("[REST-API] update GEO databases failed: %v", err)
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, err.Error())
return
}
}
}()
go func() { executor.ApplyConfig(cfg, false)
err := updater.UpdateGeoDatabases(updateNotification)
if err != nil {
errorChannel <- err
}
}()
<-done
render.NoContent(w, r) render.NoContent(w, r)
} }

26
main.go
View File

@ -113,23 +113,19 @@ func main() {
} }
if C.GeoAutoUpdate { if C.GeoAutoUpdate {
updateNotification := make(chan struct{}) updater.RegisterGeoUpdater(func() {
go updater.RegisterGeoUpdater(updateNotification) cfg, err := executor.ParseWithPath(C.Path.Config())
if err != nil {
go func() { log.Errorln("[GEO] update GEO databases failed: %v", err)
for range updateNotification { return
cfg, err := executor.ParseWithPath(C.Path.Config())
if err != nil {
log.Errorln("[GEO] update GEO databases failed: %v", err)
return
}
log.Warnln("[GEO] update GEO databases success, applying config")
executor.ApplyConfig(cfg, false)
} }
}()
log.Warnln("[GEO] update GEO databases success, applying config")
executor.ApplyConfig(cfg, false)
})
} }
defer executor.Shutdown() defer executor.Shutdown()
termSign := make(chan os.Signal, 1) termSign := make(chan os.Signal, 1)