中间件 reload

This commit is contained in:
xing 2022-11-16 10:17:29 +08:00
parent 210f8f39c5
commit c83429600b
4 changed files with 116 additions and 42 deletions

90
main.go
View File

@ -7,6 +7,7 @@ import (
"github/fthvgb1/wp-go/actions/common" "github/fthvgb1/wp-go/actions/common"
"github/fthvgb1/wp-go/config" "github/fthvgb1/wp-go/config"
"github/fthvgb1/wp-go/db" "github/fthvgb1/wp-go/db"
"github/fthvgb1/wp-go/logs"
"github/fthvgb1/wp-go/mail" "github/fthvgb1/wp-go/mail"
"github/fthvgb1/wp-go/models" "github/fthvgb1/wp-go/models"
"github/fthvgb1/wp-go/plugins" "github/fthvgb1/wp-go/plugins"
@ -19,26 +20,13 @@ import (
"time" "time"
) )
var confPath string
func init() { func init() {
var c string flag.StringVar(&confPath, "c", "config.yaml", "config file")
flag.StringVar(&c, "c", "config.yaml", "config file")
flag.Parse() flag.Parse()
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
err := config.InitConfig(c) err := initConf(confPath)
if err != nil {
panic(err)
}
err = db.InitDb()
if err != nil {
panic(err)
}
models.InitDB(db.NewSqlxDb(db.Db))
err = config.InitOptions()
if err != nil {
panic(err)
}
err = config.InitTerms()
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -48,6 +36,28 @@ func init() {
go cronClearCache() go cronClearCache()
} }
func initConf(c string) (err error) {
err = config.InitConfig(c)
if err != nil {
return
}
err = db.InitDb()
if err != nil {
return
}
models.InitDB(db.NewSqlxDb(db.Db))
err = config.InitOptions()
if err != nil {
return
}
err = config.InitTerms()
if err != nil {
return
}
return
}
func cronClearCache() { func cronClearCache() {
t := time.NewTicker(config.Conf.Load().CrontabClearCacheTime) t := time.NewTicker(config.Conf.Load().CrontabClearCacheTime)
for { for {
@ -60,30 +70,50 @@ func cronClearCache() {
} }
} }
func signalNotify() { func flushCache() {
c := make(chan os.Signal)
signal.Notify(c, syscall.SIGUSR1, syscall.SIGUSR2)
conf := config.Conf.Load()
for {
switch <-c {
case syscall.SIGUSR1:
//todo 更新配置
case syscall.SIGUSR2:
go func() {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
mail.SendMail([]string{conf.Mail.User}, "清空缓存失败", fmt.Sprintf("err:[%s]", r)) err := mail.SendMail([]string{config.Conf.Load().Mail.User}, "清空缓存失败", fmt.Sprintf("err:[%s]", r))
logs.ErrPrintln(err, "发邮件失败")
} }
}() }()
common.FlushCache() common.FlushCache()
plugins.FlushCache() plugins.FlushCache()
actions.FlushCache() actions.FlushCache()
log.Println("清除缓存成功") log.Println("清除缓存成功")
}
func reload() {
defer func() {
if r := recover(); r != nil {
log.Println(r)
}
}() }()
err := config.InitConfig(confPath)
logs.ErrPrintln(err, "获取配置文件失败", confPath)
err = config.InitOptions()
logs.ErrPrintln(err, "获取网站设置WpOption失败")
err = config.InitTerms()
logs.ErrPrintln(err, "获取WpTerms表失败")
middleWareReloadFn()
log.Println("reload complete")
}
func signalNotify() {
c := make(chan os.Signal)
signal.Notify(c, syscall.SIGUSR1, syscall.SIGUSR2)
for {
switch <-c {
case syscall.SIGUSR1:
go reload()
case syscall.SIGUSR2:
go flushCache()
} }
} }
} }
var middleWareReloadFn func()
func main() { func main() {
c := config.Conf.Load() c := config.Conf.Load()
if c.Port == "" { if c.Port == "" {
@ -91,7 +121,9 @@ func main() {
config.Conf.Store(c) config.Conf.Store(c)
} }
go signalNotify() go signalNotify()
err := route.SetupRouter().Run(c.Port) Gin, reloadFn := route.SetupRouter()
middleWareReloadFn = reloadFn
err := Gin.Run(c.Port)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -3,21 +3,33 @@ package middleware
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github/fthvgb1/wp-go/config" "github/fthvgb1/wp-go/config"
"github/fthvgb1/wp-go/helper" "github/fthvgb1/wp-go/safety"
"net/http" "net/http"
"strings" "strings"
) )
func ValidateServerNames() func(ctx *gin.Context) { func ValidateServerNames() (func(ctx *gin.Context), func()) {
serverName := helper.SimpleSliceToMap(config.Conf.Load().TrustServerNames, func(v string) string { var serverName safety.Map[string, struct{}]
return v fn := func() {
}) r := config.Conf.Load().TrustServerNames
if len(r) > 0 {
for _, name := range r {
serverName.Store(name, struct{}{})
}
} else {
serverName.Flush()
}
}
fn()
return func(c *gin.Context) { return func(c *gin.Context) {
if len(serverName) > 0 { if serverName.Len() > 0 {
if _, ok := serverName[strings.Split(c.Request.Host, ":")[0]]; !ok { if _, ok := serverName.Load(strings.Split(c.Request.Host, ":")[0]); !ok {
c.Status(http.StatusForbidden) c.Status(http.StatusForbidden)
c.Abort() c.Abort()
return
} }
} }
} c.Next()
}, fn
} }

View File

@ -16,7 +16,7 @@ import (
"time" "time"
) )
func SetupRouter() *gin.Engine { func SetupRouter() (*gin.Engine, func()) {
// Disable Console Color // Disable Console Color
// gin.DisableConsoleColor() // gin.DisableConsoleColor()
r := gin.New() r := gin.New()
@ -39,9 +39,10 @@ func SetupRouter() *gin.Engine {
return config.Options.Value(k) return config.Options.Value(k)
}, },
}).SetTemplate() }).SetTemplate()
validServerName, reloadValidServerNameFn := middleware.ValidateServerNames()
r.Use( r.Use(
gin.Logger(), gin.Logger(),
middleware.ValidateServerNames(), validServerName,
middleware.RecoverAndSendMail(gin.DefaultErrorWriter), middleware.RecoverAndSendMail(gin.DefaultErrorWriter),
middleware.FlowLimit(c.MaxRequestSleepNum, c.MaxRequestNum, c.SleepTime), middleware.FlowLimit(c.MaxRequestSleepNum, c.MaxRequestNum, c.SleepTime),
middleware.SetStaticFileCache, middleware.SetStaticFileCache,
@ -52,6 +53,9 @@ func SetupRouter() *gin.Engine {
"/wp-includes/", "/wp-content/", "/wp-includes/", "/wp-content/",
}))) })))
} }
fn := func() {
reloadValidServerNameFn()
}
f := static.Fs{FS: static.FsEx, Path: "wp-includes"} f := static.Fs{FS: static.FsEx, Path: "wp-includes"}
r.StaticFileFS("/favicon.ico", "favicon.ico", http.FS(static.FsEx)) r.StaticFileFS("/favicon.ico", "favicon.ico", http.FS(static.FsEx))
r.StaticFS("/wp-includes", http.FS(f)) r.StaticFS("/wp-includes", http.FS(f))
@ -78,5 +82,5 @@ func SetupRouter() *gin.Engine {
if gin.Mode() != gin.ReleaseMode { if gin.Mode() != gin.ReleaseMode {
pprof.Register(r, "dev/pprof") pprof.Register(r, "dev/pprof")
} }
return r return r, fn
} }

View File

@ -318,6 +318,32 @@ func (e *entry[V]) delete(px unsafe.Pointer) (value V, ok bool) {
} }
} }
func (m *Map[K, V]) Flush() {
m.mu.Lock()
m.missLocked()
m.mu.Unlock()
}
func (m *Map[K, V]) Len() int {
read, _ := m.read.Load().(readOnly[K, V])
if read.amended {
// m.dirty contains keys not in read.m. Fortunately, Range is already O(N)
// (assuming the caller does not break out early), so a call to Range
// amortizes an entire copy of the map: we can promote the dirty copy
// immediately!
m.mu.Lock()
read, _ = m.read.Load().(readOnly[K, V])
if read.amended {
read = readOnly[K, V]{m: m.dirty}
m.read.Store(read)
m.dirty = nil
m.misses = 0
}
m.mu.Unlock()
}
return len(read.m)
}
// Range calls f sequentially for each key and value present in the map. // Range calls f sequentially for each key and value present in the map.
// If f returns false, range stops the iteration. // If f returns false, range stops the iteration.
// //