You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
4.6 KiB
134 lines
4.6 KiB
package main
|
|
|
|
import (
|
|
"context"
|
|
"yunyan/comm"
|
|
"yunyan/lego"
|
|
"yunyan/modules/api"
|
|
"yunyan/modules/svccfg"
|
|
"yunyan/services"
|
|
"yunyan/sys/email"
|
|
"yunyan/sys/microsoft/translate"
|
|
"yunyan/sys/tencentyun/cos"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
|
|
"yunyan/lego/base/rpcx"
|
|
"yunyan/lego/core"
|
|
"yunyan/lego/sys/log"
|
|
"yunyan/lego/sys/mysql"
|
|
"yunyan/lego/sys/pools"
|
|
"yunyan/lego/sys/postgres"
|
|
redissys "yunyan/lego/sys/redis"
|
|
)
|
|
|
|
/*
|
|
服务类型:ai服务
|
|
*/
|
|
var (
|
|
conf = flag.String("conf", "./conf/api.yaml", "获取需要启动的服务配置文件") //启动服务的Id
|
|
)
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
s := NewService(
|
|
rpcx.SetConfPath(*conf),
|
|
rpcx.SetVersion("1.0.0.0"),
|
|
)
|
|
s.OnInstallComp( //装备组件
|
|
services.NewHttpRouteComp(),
|
|
)
|
|
lego.Run(s, //运行模块
|
|
api.NewModule(),
|
|
svccfg.NewModule(), //服务配置管理:接收配置下发,重载本服务持有的 email 客户端
|
|
)
|
|
}
|
|
|
|
func NewService(ops ...rpcx.Option) core.IService {
|
|
s := new(Service)
|
|
s.Configure(ops...)
|
|
return s
|
|
}
|
|
|
|
// worker 的服务对象定义
|
|
type Service struct {
|
|
services.ServiceBase
|
|
}
|
|
|
|
// 初始化worker需要的一些系统工具
|
|
func (this *Service) InitSys() {
|
|
this.ServiceBase.InitSys()
|
|
pools.Add(comm.Pool_UserSession, func() comm.IUserSession { return comm.NewUserSession() })
|
|
//公共库(PostgreSQL/Supabase,含只读副本)——先连,它是「服务配置托管」的 bootstrap(要先连它才能读库配置)。
|
|
if err := postgres.OnInit(this.GetSettings().Sys["postgres"]); err != nil {
|
|
panic(fmt.Sprintf("init sys.postgres err: %s", err.Error()))
|
|
} else {
|
|
log.Infof("init sys.postgres success!")
|
|
}
|
|
// 服务配置托管:库优先、无则读文件回写(seed)。应用标识由部署 .env 注入(APP_NAME/APP_REGION),
|
|
// FIELD_ENCRYPT_KEY 需与 console 一致。未配 APP_NAME 则跳过、保持纯文件配置(不产生孤儿数据)。
|
|
// 命中库配置时就地覆盖 Sys(mysql/redis/cos…),随后各 OnInit 使用被覆盖后的值。
|
|
appName, region, encKey := os.Getenv("APP_NAME"), os.Getenv("APP_REGION"), os.Getenv("FIELD_ENCRYPT_KEY")
|
|
if seeded, err := comm.LoadOrSeedServiceConfig(encKey, appName, region, "api", this.GetSettings().Sys); err != nil {
|
|
log.Warnf("init service config 托管失败(降级为纯文件配置): %s", err.Error())
|
|
} else if appName != "" {
|
|
if seeded {
|
|
log.Infof("init service config: 首次 seed 文件配置 → console 共享库 (app=%s region=%s)", appName, region)
|
|
} else {
|
|
log.Infof("init service config: 已从 console 共享库加载并覆盖文件配置 (app=%s region=%s)", appName, region)
|
|
}
|
|
}
|
|
//业务库(MySQL)
|
|
if err := mysql.OnInit(this.GetSettings().Sys["mysql"]); err != nil {
|
|
panic(fmt.Sprintf("init sys.mysql err: %s", err.Error()))
|
|
} else {
|
|
log.Infof("init sys.mysql success!")
|
|
}
|
|
// 业务功能配置:**只读覆盖、不 seed**(yaml 属主是 home,见 comm.ModuleConfigOwner)。
|
|
// 必须早于下面的 email.OnInit——api 自己也发邮件,若用 api.yaml 的旧值就会与 home 用的库值不一致。
|
|
// 失败则降级用 yaml 默认、不阻断启动。
|
|
if err := comm.LoadModuleConfig(mysql.GetSys(), os.Getenv("FIELD_ENCRYPT_KEY"), this.GetSettings().Sys); err != nil {
|
|
log.Errorf("load module config err (回退 yaml 默认): %s", err.Error())
|
|
} else {
|
|
log.Infof("load module config success!")
|
|
}
|
|
//Redis
|
|
if err := redissys.OnInit(this.GetSettings().Sys["redis"]); err != nil {
|
|
panic(fmt.Sprintf("init sys.redis err: %s", err.Error()))
|
|
} else {
|
|
log.Infof("init sys.redis success!")
|
|
}
|
|
if err := cos.OnInit(this.GetSettings().Sys["cos"]); err != nil {
|
|
panic(fmt.Sprintf("init sys.cos err: %s", err.Error()))
|
|
} else {
|
|
log.Infof("init sys.cos success!")
|
|
}
|
|
|
|
if err := email.OnInit(this.GetSettings().Sys["email"]); err != nil {
|
|
panic(fmt.Sprintf("init sys.email err: %s", err.Error()))
|
|
} else {
|
|
log.Infof("init sys.email success!")
|
|
}
|
|
|
|
if err := translate.OnInit(this.GetSettings().Sys["translate"]); err != nil {
|
|
log.Warnf("init sys.translate err: %s (翻译服务未配置,翻译功能不可用)", err.Error())
|
|
} else {
|
|
log.Infof("init sys.translate success!")
|
|
}
|
|
|
|
|
|
// 业务功能配置热重载:登记本服务可热更的 sys 与重载上下文(须在各 sys OnInit 之后)。见 configreload.go。
|
|
this.setupModuleReload()
|
|
}
|
|
|
|
func (this *Service) GetUserSession(ctx context.Context, meta map[string]string) (session comm.IUserSession) {
|
|
session = pools.Get[comm.IUserSession](comm.Pool_UserSession)
|
|
session.SetSession(ctx, meta)
|
|
return
|
|
}
|
|
|
|
func (this *Service) PutUserSession(session comm.IUserSession) {
|
|
session.Reset()
|
|
pools.Put(comm.Pool_UserSession, session)
|
|
}
|
|
|