2025-06-10 17:50:46 +08:00

142 lines
3.5 KiB
Go

package bootstrap
import (
"context"
"fmt"
"ifms/pkg/mycron"
"ifms/pkg/oss"
"net/http"
_ "net/http/pprof" //nolint:gosec
"os"
"strings"
"go.uber.org/zap"
"ifms/internal/config"
_ "ifms/internal/swagger"
"ifms/internal/utility/prom"
"ifms/internal/wirex"
"ifms/pkg/logging"
"ifms/pkg/util"
)
// RunConfig defines the config for run command.
type RunConfig struct {
WorkDir string // Working directory
Configs string // Directory or files (multiple separated by commas)
StaticDir string // Static files directory
}
// The Run function initializes and starts a service with configuration and logging, and handles
// cleanup upon exit.
func Run(ctx context.Context, runCfg RunConfig) error {
defer func() {
if err := zap.L().Sync(); err != nil {
fmt.Printf("failed to sync zap logger: %s \n", err.Error())
}
}()
// Load configuration.
workDir := runCfg.WorkDir
staticDir := runCfg.StaticDir
config.MustLoad(workDir, strings.Split(runCfg.Configs, ",")...)
config.C.General.WorkDir = workDir
config.C.Middleware.Static.Dir = staticDir
config.C.Print()
config.C.PreLoad()
// Initialize logger.
cleanLoggerFn, err := logging.InitWithConfig(ctx, &config.C.Logger, initLoggerHook)
if err != nil {
return err
}
ctx = logging.NewTag(ctx, logging.TagKeyMain)
logging.Context(ctx).Info("starting service ...",
zap.String("version", config.C.General.Version),
zap.Int("pid", os.Getpid()),
zap.String("workdir", workDir),
zap.String("config", runCfg.Configs),
zap.String("static", staticDir),
)
// 阿里云 OSS 配置
//ossConfig := oss.AliyunOssClientConfig{
// Endpoint: "oss-cn-hangzhou.aliyuncs.com",
// AccessKeyID: "LTAI5tMPLyvmGn44W6tEUzn9",
// AccessKeySecret: "YgPynRZB73nl6JbnwZg0kqZhsEpA1v",
// BucketName: "qkkj-ifms-test",
// Prefix: "test",
//}
ossConfig := oss.AliyunOssClientConfig{
Endpoint: config.C.AliyunOSS.Endpoint,
AccessKeyID: config.C.AliyunOSS.AccessKeyID,
AccessKeySecret: config.C.AliyunOSS.AccessKeySecret,
BucketName: config.C.AliyunOSS.Bucket,
}
// 初始化阿里云 OSS 客户端
client, err := oss.NewAliyunOssClient(ossConfig)
if err != nil {
logging.Context(ctx).Error("Failed to create Aliyun OSS client:", zap.Error(err))
return err
}
// 设置全局 OSS 客户端
oss.SetGlobal(func() oss.IClient {
return client
})
mycron.InitCron()
// Start pprof server.
if addr := config.C.General.PprofAddr; addr != "" {
logging.Context(ctx).Info("pprof server is listening on " + addr)
go func() {
err := http.ListenAndServe(addr, nil)
if err != nil {
logging.Context(ctx).Error("failed to listen pprof server", zap.Error(err))
}
}()
}
// Build injector.
injector, cleanInjectorFn, err := wirex.BuildInjector(ctx)
if err != nil {
return err
}
if err := injector.M.Init(ctx); err != nil {
return err
}
// Initialize global prometheus metrics.
prom.Init()
return util.Run(ctx, func(ctx context.Context) (func(), error) {
cleanHTTPServerFn, err := startHTTPServer(ctx, injector)
if err != nil {
return cleanInjectorFn, err
}
err = StartWebSocketServer()
if err != nil {
return cleanInjectorFn, err
}
return func() {
if err := injector.M.Release(ctx); err != nil {
logging.Context(ctx).Error("failed to release injector", zap.Error(err))
}
if cleanHTTPServerFn != nil {
cleanHTTPServerFn()
}
if cleanInjectorFn != nil {
cleanInjectorFn()
}
if cleanLoggerFn != nil {
cleanLoggerFn()
}
}, nil
})
}