feat: M0-M2 骨架落地(服务端/前端/宿主/数据库/积分引擎)
- server: Go 单二进制骨架,embed 内嵌前端,配置/迁移/HTTP 路由 - store: system.db + event.db 两套迁移,业务表 + 种子数据 - domain: 积分引擎(并列三口径/计分通道/流水/排名/破纪录)+ 68 个测试 - web: Vite + Vue 三入口骨架 + shared 层(类型/API/WebSocket 客户端) - console: Electron 宿主骨架(选屏/防熄屏/进程守护/托盘)
This commit is contained in:
1 parent
a61d793d79
commit
7d5d94f815
76 files changed
+10131
No files matched your search
@@ -0,0 +1,74 @@
|
||||
// Command scoreboard 是赛事积分榜系统的服务端。
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"git.yeij.top/AskaEth/Scoreboard/server/internal/config"
|
||||
"git.yeij.top/AskaEth/Scoreboard/server/internal/httpapi"
|
||||
"git.yeij.top/AskaEth/Scoreboard/server/internal/store"
|
||||
)
|
||||
|
||||
// version 由构建时注入:-ldflags "-X main.version=..."
|
||||
var version = "dev"
|
||||
|
||||
func main() {
|
||||
configPath := flag.String("config", "config.yaml", "配置文件路径")
|
||||
flag.Parse()
|
||||
|
||||
cfg, err := config.Load(*configPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "加载配置失败: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: cfg.Log.SlogLevel()}))
|
||||
slog.SetDefault(logger)
|
||||
|
||||
st, err := store.Open(cfg.DataDir)
|
||||
if err != nil {
|
||||
logger.Error("打开数据库失败", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer func() { _ = st.Close() }()
|
||||
|
||||
if err := st.Migrate(); err != nil {
|
||||
logger.Error("数据库迁移失败", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
logger.Info("数据库就绪", "dataDir", cfg.DataDir)
|
||||
|
||||
srv := &http.Server{
|
||||
Addr: cfg.Server.Addr(),
|
||||
Handler: httpapi.New(httpapi.Options{Logger: logger, Version: version}),
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
}
|
||||
|
||||
go func() {
|
||||
logger.Info("服务启动", "addr", srv.Addr, "version", version)
|
||||
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
logger.Error("服务异常退出", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer stop()
|
||||
<-ctx.Done()
|
||||
|
||||
logger.Info("正在关闭…")
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
if err := srv.Shutdown(shutdownCtx); err != nil {
|
||||
logger.Error("关闭超时", "err", err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user