Files
douyin-autojs-follower/modules/web/serve.go
2024-09-30 11:02:26 +08:00

157 lines
2.6 KiB
Go

package web
import (
"database/sql"
"fmt"
"log"
"sync"
"time"
"dyproxy/providers/db"
"github.com/fsnotify/fsnotify"
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/logger"
"github.com/gofiber/fiber/v3/middleware/recover"
"github.com/rogeecn/fabfile"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var users map[string]string = map[string]string{
"rogeecn": "xixi@0202",
}
type Config struct {
Version string
Path string
Static string
}
var config *Config
func load(f string) error {
viper.SetConfigFile(f)
viper.SetConfigType("yaml")
if err := viper.ReadInConfig(); err != nil {
return err
}
if err := viper.Unmarshal(&config); err != nil {
return err
}
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
if e.Op != fsnotify.Write {
return
}
if err := viper.Unmarshal(&config); err != nil {
log.Println(err)
}
log.Printf("config changed: %+v", config)
})
return nil
}
func ServeE(cmd *cobra.Command, args []string) error {
logrus.SetLevel(logrus.WarnLevel)
conf, err := cmd.Flags().GetString("config")
if err != nil {
return err
}
if err := load(conf); err != nil {
return err
}
db, err := db.Connect(fabfile.MustFind("data.db"))
if err != nil {
return err
}
defer db.Close()
return New(
WithDB(db),
WithLogger(),
WithRecover(),
WithRoutes(),
WithPendingCleaner(),
).Serve(9090)
}
type Option func(*WebServer)
func WithDB(db *sql.DB) Option {
return func(p *WebServer) {
p.db = db
}
}
func WithLogger() Option {
return func(s *WebServer) {
s.engine.Use(logger.New())
}
}
// WithRecover
func WithRecover() Option {
return func(s *WebServer) {
s.engine.Use(recover.New())
}
}
type WebServer struct {
db *sql.DB
engine *fiber.App
local *time.Location
pendingItems map[int32]time.Time
listLock sync.RWMutex
}
func New(opts ...Option) *WebServer {
cstSh, _ := time.LoadLocation("Asia/Shanghai")
s := &WebServer{
engine: fiber.New(),
local: cstSh,
}
for _, opt := range opts {
opt(s)
}
return s
}
// run
func (p *WebServer) Serve(port uint) error {
log.Printf("server start serve at: :%d", port)
return p.engine.Listen(fmt.Sprintf(":%d", port))
}
func WithPendingCleaner() Option {
return func(s *WebServer) {
if s.pendingItems == nil {
s.pendingItems = make(map[int32]time.Time)
}
go func() {
for range time.NewTicker(time.Minute * 1).C {
s.listLock.Lock()
for k, v := range s.pendingItems {
if time.Since(v) > time.Minute*2 {
delete(s.pendingItems, k)
}
}
s.listLock.Unlock()
}
}()
}
}