202 lines
6.4 KiB
Go
202 lines
6.4 KiB
Go
package config
|
||
|
||
import (
|
||
"net/http"
|
||
"strings"
|
||
"time"
|
||
|
||
"hyapp/pkg/configx"
|
||
"hyapp/pkg/logx"
|
||
"hyapp/pkg/tencentim"
|
||
)
|
||
|
||
// Config 描述 notice-service 启动配置。
|
||
type Config struct {
|
||
ServiceName string `yaml:"service_name"`
|
||
NodeID string `yaml:"node_id"`
|
||
Environment string `yaml:"environment"`
|
||
GRPCAddr string `yaml:"grpc_addr"`
|
||
// HealthHTTPAddr 给 CLB/发布脚本探活使用,不承载业务 HTTP。
|
||
HealthHTTPAddr string `yaml:"health_http_addr"`
|
||
// MySQLDSN 是 notice-service 自己的投递位点和死信状态库。
|
||
MySQLDSN string `yaml:"mysql_dsn"`
|
||
// WalletDatabase 是 wallet_outbox 所在库名;notice 只把它当 append-only 事实源读取。
|
||
WalletDatabase string `yaml:"wallet_database"`
|
||
// RoomDatabase 是 room_outbox 所在库名;notice 只读取需要私有通知的房间事实。
|
||
RoomDatabase string `yaml:"room_database"`
|
||
// TencentIM 是私有 IM 投递通道配置;本地默认关闭,避免误发真实消息。
|
||
TencentIM TencentIMConfig `yaml:"tencent_im"`
|
||
// WalletNoticeWorker 消费 wallet_outbox 中的 WalletBalanceChanged 事件。
|
||
WalletNoticeWorker WalletNoticeWorkerConfig `yaml:"wallet_notice_worker"`
|
||
// RoomNoticeWorker 消费 room_outbox 中需要给单个用户发送的房间通知。
|
||
RoomNoticeWorker WalletNoticeWorkerConfig `yaml:"room_notice_worker"`
|
||
MySQLAutoMigrate bool `yaml:"mysql_auto_migrate"`
|
||
Log logx.Config `yaml:"log"`
|
||
}
|
||
|
||
// TencentIMConfig 描述服务端调用腾讯云 IM REST API 的配置。
|
||
type TencentIMConfig struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
SDKAppID int64 `yaml:"sdk_app_id"`
|
||
SecretKey string `yaml:"secret_key"`
|
||
AdminIdentifier string `yaml:"admin_identifier"`
|
||
AdminUserSigTTL time.Duration `yaml:"admin_user_sig_ttl"`
|
||
Endpoint string `yaml:"endpoint"`
|
||
RequestTimeout time.Duration `yaml:"request_timeout"`
|
||
}
|
||
|
||
// RESTConfig converts YAML config into shared Tencent IM REST config.
|
||
func (c TencentIMConfig) RESTConfig() tencentim.RESTConfig {
|
||
timeout := c.RequestTimeout
|
||
if timeout <= 0 {
|
||
timeout = 5 * time.Second
|
||
}
|
||
return tencentim.RESTConfig{
|
||
SDKAppID: c.SDKAppID,
|
||
SecretKey: c.SecretKey,
|
||
AdminIdentifier: c.AdminIdentifier,
|
||
AdminUserSigTTL: c.AdminUserSigTTL,
|
||
Endpoint: c.Endpoint,
|
||
HTTPClient: &http.Client{Timeout: timeout},
|
||
}
|
||
}
|
||
|
||
// WalletNoticeWorkerConfig 控制钱包私有通知投递 worker。
|
||
type WalletNoticeWorkerConfig struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
PollInterval time.Duration `yaml:"poll_interval"`
|
||
BatchSize int `yaml:"batch_size"`
|
||
LockTTL time.Duration `yaml:"lock_ttl"`
|
||
PublishTimeout time.Duration `yaml:"publish_timeout"`
|
||
MaxRetryCount int `yaml:"max_retry_count"`
|
||
InitialBackoff time.Duration `yaml:"initial_backoff"`
|
||
MaxBackoff time.Duration `yaml:"max_backoff"`
|
||
}
|
||
|
||
// Default 返回本地开发默认配置。
|
||
func Default() Config {
|
||
return Config{
|
||
ServiceName: "notice-service",
|
||
NodeID: "notice-local",
|
||
Environment: "local",
|
||
GRPCAddr: ":13009",
|
||
HealthHTTPAddr: ":13109",
|
||
MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_notice?parseTime=true&charset=utf8mb4&loc=UTC",
|
||
WalletDatabase: "hyapp_wallet",
|
||
RoomDatabase: "hyapp_room",
|
||
MySQLAutoMigrate: false,
|
||
TencentIM: TencentIMConfig{
|
||
Enabled: false,
|
||
AdminIdentifier: "administrator",
|
||
AdminUserSigTTL: 24 * time.Hour,
|
||
Endpoint: tencentim.DefaultEndpoint,
|
||
RequestTimeout: 5 * time.Second,
|
||
},
|
||
WalletNoticeWorker: WalletNoticeWorkerConfig{
|
||
Enabled: false,
|
||
PollInterval: time.Second,
|
||
BatchSize: 100,
|
||
LockTTL: 30 * time.Second,
|
||
PublishTimeout: 3 * time.Second,
|
||
MaxRetryCount: 10,
|
||
InitialBackoff: 5 * time.Second,
|
||
MaxBackoff: 5 * time.Minute,
|
||
},
|
||
RoomNoticeWorker: WalletNoticeWorkerConfig{
|
||
Enabled: false,
|
||
PollInterval: time.Second,
|
||
BatchSize: 100,
|
||
LockTTL: 30 * time.Second,
|
||
PublishTimeout: 3 * time.Second,
|
||
MaxRetryCount: 10,
|
||
InitialBackoff: 5 * time.Second,
|
||
MaxBackoff: 5 * time.Minute,
|
||
},
|
||
Log: logx.Config{
|
||
Level: "info",
|
||
Format: "json",
|
||
MaxPayloadBytes: 2048,
|
||
},
|
||
}
|
||
}
|
||
|
||
// Load 从独立 config.yaml 读取 notice-service 配置。
|
||
func Load(path string) (Config, error) {
|
||
cfg := Default()
|
||
if path == "" {
|
||
return cfg, nil
|
||
}
|
||
if err := configx.LoadYAML(path, &cfg); err != nil {
|
||
return Config{}, err
|
||
}
|
||
cfg.ServiceName = strings.TrimSpace(cfg.ServiceName)
|
||
if cfg.ServiceName == "" {
|
||
cfg.ServiceName = "notice-service"
|
||
}
|
||
cfg.NodeID = strings.TrimSpace(cfg.NodeID)
|
||
if cfg.NodeID == "" {
|
||
cfg.NodeID = cfg.ServiceName
|
||
}
|
||
cfg.Environment = strings.ToLower(strings.TrimSpace(cfg.Environment))
|
||
if cfg.Environment == "" {
|
||
cfg.Environment = "local"
|
||
}
|
||
cfg.GRPCAddr = strings.TrimSpace(cfg.GRPCAddr)
|
||
if cfg.GRPCAddr == "" {
|
||
cfg.GRPCAddr = ":13009"
|
||
}
|
||
cfg.HealthHTTPAddr = strings.TrimSpace(cfg.HealthHTTPAddr)
|
||
if cfg.HealthHTTPAddr == "" {
|
||
cfg.HealthHTTPAddr = ":13109"
|
||
}
|
||
cfg.WalletDatabase = strings.TrimSpace(cfg.WalletDatabase)
|
||
if cfg.WalletDatabase == "" {
|
||
cfg.WalletDatabase = "hyapp_wallet"
|
||
}
|
||
cfg.RoomDatabase = strings.TrimSpace(cfg.RoomDatabase)
|
||
if cfg.RoomDatabase == "" {
|
||
cfg.RoomDatabase = "hyapp_room"
|
||
}
|
||
cfg.WalletNoticeWorker = normalizeWalletNoticeWorker(cfg.WalletNoticeWorker)
|
||
cfg.RoomNoticeWorker = normalizeWalletNoticeWorker(cfg.RoomNoticeWorker)
|
||
if strings.TrimSpace(cfg.TencentIM.AdminIdentifier) == "" {
|
||
cfg.TencentIM.AdminIdentifier = "administrator"
|
||
}
|
||
if cfg.TencentIM.AdminUserSigTTL <= 0 {
|
||
cfg.TencentIM.AdminUserSigTTL = 24 * time.Hour
|
||
}
|
||
if strings.TrimSpace(cfg.TencentIM.Endpoint) == "" {
|
||
cfg.TencentIM.Endpoint = tencentim.DefaultEndpoint
|
||
}
|
||
if cfg.TencentIM.RequestTimeout <= 0 {
|
||
cfg.TencentIM.RequestTimeout = 5 * time.Second
|
||
}
|
||
return cfg, nil
|
||
}
|
||
|
||
func normalizeWalletNoticeWorker(cfg WalletNoticeWorkerConfig) WalletNoticeWorkerConfig {
|
||
def := Default().WalletNoticeWorker
|
||
if cfg.PollInterval <= 0 {
|
||
cfg.PollInterval = def.PollInterval
|
||
}
|
||
if cfg.BatchSize <= 0 {
|
||
cfg.BatchSize = def.BatchSize
|
||
}
|
||
if cfg.LockTTL <= 0 {
|
||
cfg.LockTTL = def.LockTTL
|
||
}
|
||
if cfg.PublishTimeout <= 0 {
|
||
cfg.PublishTimeout = def.PublishTimeout
|
||
}
|
||
if cfg.MaxRetryCount <= 0 {
|
||
cfg.MaxRetryCount = def.MaxRetryCount
|
||
}
|
||
if cfg.InitialBackoff <= 0 {
|
||
cfg.InitialBackoff = def.InitialBackoff
|
||
}
|
||
if cfg.MaxBackoff <= 0 {
|
||
cfg.MaxBackoff = def.MaxBackoff
|
||
}
|
||
return cfg
|
||
}
|