feat: init
This commit is contained in:
156
modules/web/serve.go
Normal file
156
modules/web/serve.go
Normal file
@@ -0,0 +1,156 @@
|
||||
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()
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user