Browse Source

feat: cron service of assets module

feature/assets
Dnomd343 1 year ago
parent
commit
79939308b8
  1. 129
      next/assets/assets.go
  2. 11
      next/assets/update.go
  3. 21
      next/main.go

129
next/assets/assets.go

@ -2,6 +2,7 @@ package assets
import (
"XProxy/next/logger"
"github.com/robfig/cron"
urlpkg "net/url"
"strings"
"sync"
@ -12,63 +13,109 @@ var buildinAssets = map[string]string{
"geosite.dat": "/geosite.dat.xz",
}
type UpdateSettings struct {
cron string
mutex sync.Mutex
type updateConfig struct {
spec string
cron *cron.Cron
renew sync.Mutex
running sync.Mutex
proxy *urlpkg.URL
assets map[string]string
}
var update UpdateSettings
var update updateConfig
func assetsClone(raw map[string]string) map[string]string {
assets := make(map[string]string, len(raw))
for file, url := range raw {
assets[file] = strings.Clone(url)
}
return assets
}
//func assetsClone(raw map[string]string) map[string]string {
// assets := make(map[string]string, len(raw))
// for file, url := range raw {
// assets[file] = strings.Clone(url)
// }
// return assets
//}
func SetCron(cron string) error {
// TODO: setting up crond service
return nil
// GetCron is used to obtain cron service specification.
func GetCron() string {
update.renew.Lock()
spec := strings.Clone(update.spec)
update.renew.Unlock()
return spec
}
func GetProxy() string {
update.mutex.Lock()
proxy := update.proxy.String()
update.mutex.Unlock()
return proxy
}
// SetCron is used to update cron service specification.
func SetCron(spec string) error {
if spec == update.spec {
return nil // cron spec without renew
}
func SetProxy(proxy string) error {
var proxyUrl *urlpkg.URL // clear proxy by empty string
if proxy != "" {
url, err := urlpkg.Parse(proxy)
var cs *cron.Cron
if spec != "" { // update cron service
cs = cron.New()
err := cs.AddFunc(spec, func() {
var entry *cron.Entry
if entries := update.cron.Entries(); len(entries) != 0 && entries[0] != nil {
entry = entries[0]
}
logger.Debugf("hello from cron")
if entry != nil {
logger.Debugf("Assets cron service next trigger -> `%s`", entry.Next)
}
})
if err != nil {
logger.Errorf("Invalid proxy url `%s` -> %v", proxy, err)
logger.Errorf("Invalid cron spec `%s` -> %v", spec, err)
return err
}
proxyUrl = url
cs.Start()
}
update.mutex.Lock()
update.proxy = proxyUrl
update.mutex.Unlock()
return nil
}
func SetAssets(assets map[string]string) {
update.mutex.Lock()
update.assets = assetsClone(assets)
update.mutex.Unlock()
update.renew.Lock()
if update.cron != nil {
update.cron.Stop() // stop old cron service
}
update.cron = cs
update.spec = spec
if cs == nil {
logger.Infof("Assets cron service has been terminated")
} else {
logger.Infof("Assets cron service has been updated -> `%s`", spec)
}
update.renew.Unlock()
return nil
}
func GetAssets() map[string]string {
update.mutex.Lock()
assets := assetsClone(update.assets)
update.mutex.Unlock()
return assets
}
//func GetProxy() string {
// update.mutex.Lock()
// proxy := update.proxy.String()
// update.mutex.Unlock()
// return proxy
//}
//
//func SetProxy(proxy string) error {
// var proxyUrl *urlpkg.URL // clear proxy by empty string
// if proxy != "" {
// url, err := urlpkg.Parse(proxy)
// if err != nil {
// logger.Errorf("Invalid proxy url `%s` -> %v", proxy, err)
// return err
// }
// proxyUrl = url
// }
// update.mutex.Lock()
// update.proxy = proxyUrl
// update.mutex.Unlock()
// return nil
//}
//
//func SetAssets(assets map[string]string) {
// update.mutex.Lock()
// update.assets = assetsClone(assets)
// update.mutex.Unlock()
//}
//
//func GetAssets() map[string]string {
// update.mutex.Lock()
// assets := assetsClone(update.assets)
// update.mutex.Unlock()
// return assets
//}
func LoadBuildin() {
updateLocalAssets(buildinAssets, true)

11
next/assets/update.go

@ -4,6 +4,7 @@ import (
"XProxy/next/logger"
urlpkg "net/url"
"os"
"path"
"sync"
"time"
)
@ -11,14 +12,18 @@ import (
// saveAsset is used to write to a local file and specify its last modify
// time. If the file exists, it will be replaced.
func saveAsset(file string, content []byte, date *time.Time) error {
// TODO: create folder if not exist
err := os.MkdirAll(path.Dir(file), 0755)
if err != nil {
logger.Errorf("Failed to create folder -> %v", err)
return err
}
fp, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
logger.Errorf("Failed to open file `%s` -> %v", file, err)
logger.Errorf("Failed to open file -> %v", err)
return err
}
defer fp.Close()
_, err = fp.Write(content)
if err != nil {
logger.Errorf("Failed to save file `%s` -> %v", file, err)

21
next/main.go

@ -1,10 +1,27 @@
package main
import "XProxy/next/assets"
import (
"XProxy/next/assets"
"XProxy/next/logger"
"time"
)
func main() {
assets.LoadBuildin()
logger.Warnf("cron -> `%s`", assets.GetCron())
assets.SetCron("@every 1s")
logger.Warnf("cron -> `%s`", assets.GetCron())
time.Sleep(5 * time.Second)
assets.SetCron("@every 2s")
logger.Warnf("cron -> `%s`", assets.GetCron())
time.Sleep(8 * time.Second)
assets.SetCron("")
logger.Warnf("cron -> `%s`", assets.GetCron())
select {}
//assets.LoadBuildin()
//remoteAssets := map[string]string{
// "geoip.dat": "https://cdn.dnomd343.top/v2ray-rules-dat/geoip.dat.xz",

Loading…
Cancel
Save