Files
go-admin/cmd/api/server.go
zhangwenjian 82ea8539eb chore🔧: upgrade go-admin-core and route the queue through configuration
The pinned core dated from April, before sdk stopped being a separate module,
so the build resolved sdk packages from the old module and core packages from
the new one. Dropping the separate requirement is what makes the two agree
again.

Most of the diff is renames that came with that: the tenant accessors gained a
ByTenant suffix, GetDb now returns one database and GetAllDb the map, and
casbin moved to v3.

The change that matters is four call sites moving from GetMemoryQueue to
GetQueuePrefix. GetMemoryQueue returns a queue fixed at construction, so the
login log, the operate log and the api check ran in process no matter what the
settings file selected — a second instance saw none of it. GetQueuePrefix
returns whatever the configuration built, which is the point of being able to
configure a queue at all.

Verified against core at main: build and vet clean. The two file_store failures
are unchanged from before this branch; they need cloud credentials.
2026-08-18 22:14:08 +08:00

189 lines
5.1 KiB
Go

package api
import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"time"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/config/source/file"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk"
"github.com/go-admin-team/go-admin-core/sdk/api"
"github.com/go-admin-team/go-admin-core/sdk/config"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"go-admin/app/admin/models"
"go-admin/app/admin/router"
"go-admin/app/jobs"
"go-admin/common/database"
"go-admin/common/global"
common "go-admin/common/middleware"
"go-admin/common/middleware/handler"
"go-admin/common/storage"
ext "go-admin/config"
)
var (
configYml string
apiCheck bool
StartCmd = &cobra.Command{
Use: "server",
Short: "Start API server",
Example: "go-admin server -c config/settings.yml",
SilenceUsage: true,
PreRun: func(cmd *cobra.Command, args []string) {
setup()
},
RunE: func(cmd *cobra.Command, args []string) error {
return run()
},
}
)
var AppRouters = make([]func(), 0)
func init() {
StartCmd.PersistentFlags().StringVarP(&configYml, "config", "c", "config/settings.yml", "Start server with provided configuration file")
StartCmd.PersistentFlags().BoolVarP(&apiCheck, "api", "a", false, "Start server with check api data")
//注册路由 fixme 其他应用的路由,在本目录新建文件放在init方法
AppRouters = append(AppRouters, router.InitRouter)
}
func setup() {
// 注入配置扩展项
config.ExtendConfig = &ext.ExtConfig
//1. 读取配置
config.Setup(
file.NewSource(file.WithPath(configYml)),
database.Setup,
storage.Setup,
)
//注册监听函数
queue := sdk.Runtime.GetQueuePrefix("")
queue.Register(global.LoginLog, models.SaveLoginLog)
queue.Register(global.OperateLog, models.SaveOperaLog)
queue.Register(global.ApiCheck, models.SaveSysApi)
go queue.Run()
usageStr := `starting api server...`
log.Info(usageStr)
}
func run() error {
if config.ApplicationConfig.Mode == pkg.ModeProd.String() {
gin.SetMode(gin.ReleaseMode)
}
initRouter()
for _, f := range AppRouters {
f()
}
srv := &http.Server{
Addr: fmt.Sprintf("%s:%d", config.ApplicationConfig.Host, config.ApplicationConfig.Port),
Handler: sdk.Runtime.GetEngine(),
ReadTimeout: time.Duration(config.ApplicationConfig.ReadTimeout) * time.Second,
WriteTimeout: time.Duration(config.ApplicationConfig.WriterTimeout) * time.Second,
}
go func() {
jobs.InitJob()
jobs.Setup(sdk.Runtime.GetAllDb())
}()
if apiCheck {
var routers = sdk.Runtime.GetRouter()
q := sdk.Runtime.GetQueuePrefix("")
mp := make(map[string]interface{})
mp["List"] = routers
message, err := sdk.Runtime.GetStreamMessage("", global.ApiCheck, mp)
if err != nil {
log.Infof("GetStreamMessage error, %s \n", err.Error())
//日志报错错误,不中断请求
} else {
err = q.Append(message)
if err != nil {
log.Infof("Append message error, %s \n", err.Error())
}
}
}
go func() {
// 服务连接
if config.SslConfig.Enable {
if err := srv.ListenAndServeTLS(config.SslConfig.Pem, config.SslConfig.KeyStr); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatal("listen: ", err)
}
} else {
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatal("listen: ", err)
}
}
}()
fmt.Println(pkg.Red(string(global.LogoContent)))
tip()
fmt.Println(pkg.Green("Server run at:"))
fmt.Printf("- Local: %s://localhost:%d/ \r\n", "http", config.ApplicationConfig.Port)
fmt.Printf("- Network: %s://%s:%d/ \r\n", "http", pkg.GetLocalHost(), config.ApplicationConfig.Port)
fmt.Println(pkg.Green("Swagger run at:"))
fmt.Printf("- Local: http://localhost:%d/swagger/admin/index.html \r\n", config.ApplicationConfig.Port)
fmt.Printf("- Network: %s://%s:%d/swagger/admin/index.html \r\n", "http", pkg.GetLocalHost(), config.ApplicationConfig.Port)
fmt.Printf("%s Enter Control + C Shutdown Server \r\n", pkg.GetCurrentTimeStr())
// 等待中断信号以优雅地关闭服务器(设置 5 秒的超时时间)
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt)
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
log.Info("Shutdown Server ... ")
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
log.Info("Server exiting")
return nil
}
//var Router runtime.Router
func tip() {
usageStr := `欢迎使用 ` + pkg.Green(`go-admin `+global.Version) + ` 可以使用 ` + pkg.Red(`-h`) + ` 查看命令`
fmt.Printf("%s \n\n", usageStr)
}
func initRouter() {
var r *gin.Engine
h := sdk.Runtime.GetEngine()
if h == nil {
h = gin.New()
sdk.Runtime.SetEngine(h)
}
switch h.(type) {
case *gin.Engine:
r = h.(*gin.Engine)
default:
log.Fatal("not support other engine")
//os.Exit(-1)
}
if config.SslConfig.Enable {
r.Use(handler.TlsHandler())
}
//r.Use(middleware.Metrics())
r.Use(common.Sentinel()).
Use(common.RequestId(pkg.TrafficKey)).
Use(api.SetRequestLogger)
common.InitMiddleware(r)
}