585 lines
26 KiB
Go
585 lines
26 KiB
Go
package config
|
||
|
||
import (
|
||
"errors"
|
||
"net/http"
|
||
"strings"
|
||
"time"
|
||
|
||
"hyapp/pkg/configx"
|
||
"hyapp/pkg/logx"
|
||
"hyapp/pkg/tencentim"
|
||
)
|
||
|
||
// Config 描述 activity-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 是活动状态、事件消费幂等和 outbox 的必需存储连接串。
|
||
MySQLDSN string `yaml:"mysql_dsn"`
|
||
// UserServiceAddr 是 fanout worker 读取目标用户游标的内部 gRPC 地址。
|
||
UserServiceAddr string `yaml:"user_service_addr"`
|
||
// WalletServiceAddr 是任务奖励入账依赖;activity 只发命令,不直接写余额。
|
||
WalletServiceAddr string `yaml:"wallet_service_addr"`
|
||
// RoomServiceAddr 是房间流水奖励结算读取房主快照的内部 gRPC 地址。
|
||
RoomServiceAddr string `yaml:"room_service_addr"`
|
||
// FirstRechargeRewardWorker 控制首冲奖励对 wallet_outbox 充值事实的本地消费。
|
||
FirstRechargeRewardWorker FirstRechargeRewardWorkerConfig `yaml:"first_recharge_reward_worker"`
|
||
// CumulativeRechargeRewardWorker 控制累充奖励对 wallet_outbox 充值事实的本地消费。
|
||
CumulativeRechargeRewardWorker CumulativeRechargeRewardWorkerConfig `yaml:"cumulative_recharge_reward_worker"`
|
||
// InviteActivityRewardWorker 控制邀请活动对 wallet/user outbox 事实的本地消费。
|
||
InviteActivityRewardWorker InviteActivityRewardWorkerConfig `yaml:"invite_activity_reward_worker"`
|
||
// RedPacketBroadcastWorker 控制红包创建事实转区域飘屏 outbox 的本地消费。
|
||
RedPacketBroadcastWorker RedPacketBroadcastWorkerConfig `yaml:"red_packet_broadcast_worker"`
|
||
// TaskEventWorker 控制任务系统对 wallet/user outbox 事实的本地消费。
|
||
TaskEventWorker TaskEventWorkerConfig `yaml:"task_event_worker"`
|
||
// UserLeaderboardWorker 控制用户送礼榜单对 wallet_outbox 送礼事实的 Redis 投影。
|
||
UserLeaderboardWorker UserLeaderboardWorkerConfig `yaml:"user_leaderboard_worker"`
|
||
// LuckyGiftWorker 控制幸运礼物 draw outbox 的返奖和房间 IM 补偿。
|
||
LuckyGiftWorker LuckyGiftWorkerConfig `yaml:"lucky_gift_worker"`
|
||
// TencentIM 是 activity-service 发送全局/区域播报群消息的 REST 配置。
|
||
TencentIM TencentIMConfig `yaml:"tencent_im"`
|
||
// Broadcast 控制 IM 播报群 reconciler、outbox worker 和贵重礼物阈值。
|
||
Broadcast BroadcastConfig `yaml:"broadcast"`
|
||
// RocketMQ 可直接消费 room-service 发布的 room_outbox fanout topic。
|
||
RocketMQ RocketMQConfig `yaml:"rocketmq"`
|
||
// MySQLAutoMigrate 保留给显式本地迁移;线上 schema 由发布流程或 initdb 管理。
|
||
MySQLAutoMigrate bool `yaml:"mysql_auto_migrate"`
|
||
Consumer ConsumerConfig `yaml:"consumer"`
|
||
MessageInbox MessageInboxConfig `yaml:"message_inbox"`
|
||
// MessageActionConfirmWorker 控制通用确认消息的 user_outbox 消费和 IM outbox 发布。
|
||
MessageActionConfirmWorker MessageActionConfirmWorkerConfig `yaml:"message_action_confirm_worker"`
|
||
Log logx.Config `yaml:"log"`
|
||
}
|
||
|
||
// ConsumerConfig 保存 room outbox 消费底座配置。
|
||
type ConsumerConfig struct {
|
||
RoomOutboxPollIntervalMs int64 `yaml:"room_outbox_poll_interval_ms"`
|
||
BatchSize int `yaml:"batch_size"`
|
||
}
|
||
|
||
// MessageInboxConfig 保存 App system/activity inbox 的读取缓存参数;fanout 扫描由 cron-service 调度。
|
||
type MessageInboxConfig struct {
|
||
UnreadCacheTTL string `yaml:"unread_cache_ttl"`
|
||
}
|
||
|
||
// MessageActionConfirmWorkerConfig 保存确认消息消费和 MQ 发布策略。
|
||
type MessageActionConfirmWorkerConfig struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
OutboxPollInterval time.Duration `yaml:"outbox_poll_interval"`
|
||
OutboxBatchSize int `yaml:"outbox_batch_size"`
|
||
OutboxLockTTL time.Duration `yaml:"outbox_lock_ttl"`
|
||
OutboxMaxRetry int `yaml:"outbox_max_retry"`
|
||
PublishTimeout time.Duration `yaml:"publish_timeout"`
|
||
}
|
||
|
||
// FirstRechargeRewardWorkerConfig 保存钱包充值事实消费策略。
|
||
type FirstRechargeRewardWorkerConfig struct {
|
||
// Enabled 控制是否启动 wallet_outbox MQ 消费;关闭后仍可通过 gRPC 消费入口补偿。
|
||
Enabled bool `yaml:"enabled"`
|
||
}
|
||
|
||
// CumulativeRechargeRewardWorkerConfig 保存累充奖励钱包充值事实消费策略。
|
||
type CumulativeRechargeRewardWorkerConfig struct {
|
||
// Enabled 控制是否启动 wallet_outbox MQ 消费;关闭后仍可通过 gRPC 消费入口补偿。
|
||
Enabled bool `yaml:"enabled"`
|
||
}
|
||
|
||
// InviteActivityRewardWorkerConfig 保存邀请活动钱包和用户事实消费策略。
|
||
type InviteActivityRewardWorkerConfig struct {
|
||
// Enabled 控制是否启动 wallet/user outbox MQ 消费。
|
||
Enabled bool `yaml:"enabled"`
|
||
}
|
||
|
||
// RedPacketBroadcastWorkerConfig 保存红包创建事实消费策略。
|
||
type RedPacketBroadcastWorkerConfig struct {
|
||
// Enabled 控制是否启动 wallet_outbox MQ 消费。
|
||
Enabled bool `yaml:"enabled"`
|
||
}
|
||
|
||
// TaskEventWorkerConfig 保存任务进度事实消费策略。
|
||
type TaskEventWorkerConfig struct {
|
||
// Enabled 控制是否启动 wallet/user outbox 任务消费者;room outbox 任务投影跟随 room_outbox 主消费者。
|
||
Enabled bool `yaml:"enabled"`
|
||
}
|
||
|
||
// UserLeaderboardWorkerConfig 保存用户送礼榜单 Redis 投影策略。
|
||
type UserLeaderboardWorkerConfig struct {
|
||
// Enabled 控制是否启动 wallet_outbox 用户榜单消费者;关闭时 gateway 只能读到已有 Redis 聚合。
|
||
Enabled bool `yaml:"enabled"`
|
||
// RedisAddr 是 activity 写入用户榜单聚合的 Redis 地址,必须与 gateway 读取地址一致。
|
||
RedisAddr string `yaml:"redis_addr"`
|
||
// RedisPassword 是 Redis 鉴权密码,本地默认留空。
|
||
RedisPassword string `yaml:"redis_password"`
|
||
// RedisDB 是 Redis logical DB,必须与 gateway 读取配置一致。
|
||
RedisDB int `yaml:"redis_db"`
|
||
// KeyPrefix 隔离用户榜单 key,必须与 gateway 读取配置一致。
|
||
KeyPrefix string `yaml:"key_prefix"`
|
||
}
|
||
|
||
// LuckyGiftWorkerConfig 保存幸运礼物抽奖副作用补偿策略。
|
||
type LuckyGiftWorkerConfig struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
WorkerPollInterval time.Duration `yaml:"worker_poll_interval"`
|
||
WorkerBatchSize int `yaml:"worker_batch_size"`
|
||
WorkerConcurrency int `yaml:"worker_concurrency"`
|
||
WorkerLockTTL time.Duration `yaml:"worker_lock_ttl"`
|
||
WorkerMaxRetry int `yaml:"worker_max_retry"`
|
||
PublishTimeout time.Duration `yaml:"publish_timeout"`
|
||
StatsRefreshInterval time.Duration `yaml:"stats_refresh_interval"`
|
||
StatsBatchSize int `yaml:"stats_batch_size"`
|
||
}
|
||
|
||
// TencentIMConfig 描述 activity-service 调用腾讯云 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"`
|
||
GroupType string `yaml:"group_type"`
|
||
GroupIDPrefix string `yaml:"group_id_prefix"`
|
||
RequestTimeout time.Duration `yaml:"request_timeout"`
|
||
}
|
||
|
||
// RESTConfig converts YAML into the shared Tencent IM REST client 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,
|
||
GroupType: c.GroupType,
|
||
HTTPClient: &http.Client{Timeout: timeout},
|
||
}
|
||
}
|
||
|
||
// BroadcastConfig stores activity-service broadcast worker policy.
|
||
type BroadcastConfig struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
SuperGiftMinValue int64 `yaml:"super_gift_min_value"`
|
||
WorkerPollInterval time.Duration `yaml:"worker_poll_interval"`
|
||
WorkerBatchSize int `yaml:"worker_batch_size"`
|
||
WorkerLockTTL time.Duration `yaml:"worker_lock_ttl"`
|
||
WorkerMaxRetry int `yaml:"worker_max_retry"`
|
||
EnsureGroupsOnStartup bool `yaml:"ensure_groups_on_startup"`
|
||
}
|
||
|
||
// RocketMQConfig 描述 activity-service 消费房间事实的 MQ 连接。
|
||
type RocketMQConfig struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
NameServers []string `yaml:"name_servers"`
|
||
NameServerDomain string `yaml:"name_server_domain"`
|
||
AccessKey string `yaml:"access_key"`
|
||
SecretKey string `yaml:"secret_key"`
|
||
SecurityToken string `yaml:"security_token"`
|
||
Namespace string `yaml:"namespace"`
|
||
VIPChannel bool `yaml:"vip_channel"`
|
||
RoomOutbox RoomOutboxMQConfig `yaml:"room_outbox"`
|
||
WalletOutbox WalletOutboxMQConfig `yaml:"wallet_outbox"`
|
||
UserOutbox UserOutboxMQConfig `yaml:"user_outbox"`
|
||
MessageActionOutbox MessageActionOutboxMQConfig `yaml:"message_action_outbox"`
|
||
}
|
||
|
||
// RoomOutboxMQConfig 控制 activity 对 room_outbox topic 的消费位点。
|
||
type RoomOutboxMQConfig struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
Topic string `yaml:"topic"`
|
||
ConsumerGroup string `yaml:"consumer_group"`
|
||
ConsumerMaxReconsumeTimes int32 `yaml:"consumer_max_reconsume_times"`
|
||
}
|
||
|
||
// WalletOutboxMQConfig 控制 activity 对 wallet_outbox topic 的独立消费组。
|
||
type WalletOutboxMQConfig struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
Topic string `yaml:"topic"`
|
||
RealtimeTopic string `yaml:"realtime_topic"`
|
||
FirstRechargeConsumerGroup string `yaml:"first_recharge_consumer_group"`
|
||
CumulativeRechargeConsumerGroup string `yaml:"cumulative_recharge_consumer_group"`
|
||
InviteActivityConsumerGroup string `yaml:"invite_activity_consumer_group"`
|
||
RedPacketBroadcastConsumerGroup string `yaml:"red_packet_broadcast_consumer_group"`
|
||
TaskConsumerGroup string `yaml:"task_consumer_group"`
|
||
UserLeaderboardConsumerGroup string `yaml:"user_leaderboard_consumer_group"`
|
||
ConsumerMaxReconsumeTimes int32 `yaml:"consumer_max_reconsume_times"`
|
||
}
|
||
|
||
// UserOutboxMQConfig 控制 activity 对 user_outbox topic 的独立消费组。
|
||
type UserOutboxMQConfig struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
Topic string `yaml:"topic"`
|
||
ConsumerGroup string `yaml:"consumer_group"`
|
||
TaskConsumerGroup string `yaml:"task_consumer_group"`
|
||
InviteActivityConsumerGroup string `yaml:"invite_activity_consumer_group"`
|
||
MessageActionConsumerGroup string `yaml:"message_action_consumer_group"`
|
||
ConsumerMaxReconsumeTimes int32 `yaml:"consumer_max_reconsume_times"`
|
||
}
|
||
|
||
// MessageActionOutboxMQConfig 控制确认消息 outbox 投递到 notice-service 的 MQ producer。
|
||
type MessageActionOutboxMQConfig struct {
|
||
Enabled bool `yaml:"enabled"`
|
||
Topic string `yaml:"topic"`
|
||
ProducerGroup string `yaml:"producer_group"`
|
||
SendTimeout time.Duration `yaml:"send_timeout"`
|
||
Retry int `yaml:"retry"`
|
||
}
|
||
|
||
// Default 返回本地默认配置。
|
||
func Default() Config {
|
||
return Config{
|
||
ServiceName: "activity-service",
|
||
NodeID: "activity-local",
|
||
Environment: "local",
|
||
GRPCAddr: ":13006",
|
||
HealthHTTPAddr: ":13106",
|
||
MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_activity?parseTime=true&charset=utf8mb4&loc=UTC",
|
||
UserServiceAddr: "127.0.0.1:13005",
|
||
WalletServiceAddr: "127.0.0.1:13004",
|
||
RoomServiceAddr: "127.0.0.1:13001",
|
||
FirstRechargeRewardWorker: FirstRechargeRewardWorkerConfig{
|
||
Enabled: false,
|
||
},
|
||
CumulativeRechargeRewardWorker: CumulativeRechargeRewardWorkerConfig{
|
||
Enabled: false,
|
||
},
|
||
InviteActivityRewardWorker: InviteActivityRewardWorkerConfig{
|
||
Enabled: true,
|
||
},
|
||
RedPacketBroadcastWorker: RedPacketBroadcastWorkerConfig{
|
||
Enabled: false,
|
||
},
|
||
TaskEventWorker: TaskEventWorkerConfig{
|
||
Enabled: true,
|
||
},
|
||
UserLeaderboardWorker: UserLeaderboardWorkerConfig{
|
||
Enabled: false,
|
||
},
|
||
MessageActionConfirmWorker: MessageActionConfirmWorkerConfig{
|
||
Enabled: true,
|
||
OutboxPollInterval: time.Second,
|
||
OutboxBatchSize: 100,
|
||
OutboxLockTTL: 30 * time.Second,
|
||
OutboxMaxRetry: 8,
|
||
PublishTimeout: 5 * time.Second,
|
||
},
|
||
LuckyGiftWorker: LuckyGiftWorkerConfig{
|
||
Enabled: false,
|
||
WorkerPollInterval: time.Second,
|
||
WorkerBatchSize: 100,
|
||
WorkerConcurrency: 4,
|
||
WorkerLockTTL: 30 * time.Second,
|
||
WorkerMaxRetry: 8,
|
||
PublishTimeout: 5 * time.Second,
|
||
StatsRefreshInterval: 10 * time.Minute,
|
||
StatsBatchSize: 5000,
|
||
},
|
||
TencentIM: TencentIMConfig{
|
||
Enabled: false,
|
||
AdminIdentifier: "administrator",
|
||
AdminUserSigTTL: 24 * time.Hour,
|
||
Endpoint: tencentim.DefaultEndpoint,
|
||
GroupType: tencentim.DefaultGroupType,
|
||
RequestTimeout: 5 * time.Second,
|
||
},
|
||
Broadcast: BroadcastConfig{
|
||
Enabled: false,
|
||
SuperGiftMinValue: 100000,
|
||
WorkerPollInterval: time.Second,
|
||
WorkerBatchSize: 100,
|
||
WorkerLockTTL: 30 * time.Second,
|
||
WorkerMaxRetry: 8,
|
||
EnsureGroupsOnStartup: true,
|
||
},
|
||
RocketMQ: defaultRocketMQConfig(),
|
||
MySQLAutoMigrate: false,
|
||
Consumer: ConsumerConfig{
|
||
RoomOutboxPollIntervalMs: 1000,
|
||
BatchSize: 100,
|
||
},
|
||
MessageInbox: MessageInboxConfig{
|
||
UnreadCacheTTL: "60s",
|
||
},
|
||
Log: logx.Config{
|
||
Level: "info",
|
||
Format: "json",
|
||
MaxPayloadBytes: 2048,
|
||
},
|
||
}
|
||
}
|
||
|
||
func defaultRocketMQConfig() RocketMQConfig {
|
||
return RocketMQConfig{
|
||
Enabled: false,
|
||
RoomOutbox: RoomOutboxMQConfig{
|
||
Enabled: false,
|
||
Topic: "hyapp_room_outbox",
|
||
ConsumerGroup: "hyapp-activity-room-outbox",
|
||
ConsumerMaxReconsumeTimes: 16,
|
||
},
|
||
WalletOutbox: WalletOutboxMQConfig{
|
||
Enabled: false,
|
||
Topic: "hyapp_wallet_outbox",
|
||
RealtimeTopic: "",
|
||
FirstRechargeConsumerGroup: "hyapp-activity-first-recharge-wallet-outbox",
|
||
CumulativeRechargeConsumerGroup: "hyapp-activity-cumulative-recharge-wallet-outbox",
|
||
InviteActivityConsumerGroup: "hyapp-activity-invite-wallet-outbox",
|
||
RedPacketBroadcastConsumerGroup: "hyapp-activity-red-packet-wallet-outbox",
|
||
TaskConsumerGroup: "hyapp-activity-task-wallet-outbox",
|
||
UserLeaderboardConsumerGroup: "hyapp-activity-user-leaderboard-wallet-outbox",
|
||
ConsumerMaxReconsumeTimes: 16,
|
||
},
|
||
UserOutbox: UserOutboxMQConfig{
|
||
Enabled: false,
|
||
Topic: "hyapp_user_outbox",
|
||
ConsumerGroup: "hyapp-activity-user-region-broadcast",
|
||
TaskConsumerGroup: "hyapp-activity-task-user-outbox",
|
||
InviteActivityConsumerGroup: "hyapp-activity-invite-user-outbox",
|
||
MessageActionConsumerGroup: "hyapp-activity-message-action-user-outbox",
|
||
ConsumerMaxReconsumeTimes: 16,
|
||
},
|
||
MessageActionOutbox: MessageActionOutboxMQConfig{
|
||
Enabled: false,
|
||
Topic: "hyapp_message_action_outbox",
|
||
ProducerGroup: "hyapp-activity-message-action-outbox",
|
||
SendTimeout: 5 * time.Second,
|
||
Retry: 2,
|
||
},
|
||
}
|
||
}
|
||
|
||
// Load 从独立 config.yaml 读取 activity-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
|
||
}
|
||
if strings.TrimSpace(cfg.UserServiceAddr) == "" {
|
||
cfg.UserServiceAddr = Default().UserServiceAddr
|
||
}
|
||
if strings.TrimSpace(cfg.WalletServiceAddr) == "" {
|
||
cfg.WalletServiceAddr = Default().WalletServiceAddr
|
||
}
|
||
if strings.TrimSpace(cfg.RoomServiceAddr) == "" {
|
||
cfg.RoomServiceAddr = Default().RoomServiceAddr
|
||
}
|
||
cfg.ServiceName = strings.TrimSpace(cfg.ServiceName)
|
||
if cfg.ServiceName == "" {
|
||
cfg.ServiceName = "activity-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.HealthHTTPAddr = strings.TrimSpace(cfg.HealthHTTPAddr)
|
||
if cfg.HealthHTTPAddr == "" {
|
||
cfg.HealthHTTPAddr = ":13106"
|
||
}
|
||
cfg.TencentIM.AdminIdentifier = strings.TrimSpace(cfg.TencentIM.AdminIdentifier)
|
||
if cfg.TencentIM.AdminIdentifier == "" {
|
||
cfg.TencentIM.AdminIdentifier = "administrator"
|
||
}
|
||
cfg.TencentIM.Endpoint = strings.TrimSpace(cfg.TencentIM.Endpoint)
|
||
if cfg.TencentIM.Endpoint == "" {
|
||
cfg.TencentIM.Endpoint = tencentim.DefaultEndpoint
|
||
}
|
||
cfg.TencentIM.GroupType = strings.TrimSpace(cfg.TencentIM.GroupType)
|
||
if cfg.TencentIM.GroupType == "" {
|
||
cfg.TencentIM.GroupType = tencentim.DefaultGroupType
|
||
}
|
||
cfg.TencentIM.GroupIDPrefix = strings.TrimSpace(cfg.TencentIM.GroupIDPrefix)
|
||
if cfg.TencentIM.AdminUserSigTTL <= 0 {
|
||
cfg.TencentIM.AdminUserSigTTL = 24 * time.Hour
|
||
}
|
||
if cfg.TencentIM.RequestTimeout <= 0 {
|
||
cfg.TencentIM.RequestTimeout = 5 * time.Second
|
||
}
|
||
if cfg.Broadcast.SuperGiftMinValue <= 0 {
|
||
cfg.Broadcast.SuperGiftMinValue = 100000
|
||
}
|
||
if cfg.Broadcast.WorkerPollInterval <= 0 {
|
||
cfg.Broadcast.WorkerPollInterval = time.Second
|
||
}
|
||
if cfg.Broadcast.WorkerBatchSize <= 0 {
|
||
cfg.Broadcast.WorkerBatchSize = 100
|
||
}
|
||
if cfg.Broadcast.WorkerLockTTL <= 0 {
|
||
cfg.Broadcast.WorkerLockTTL = 30 * time.Second
|
||
}
|
||
if cfg.Broadcast.WorkerMaxRetry <= 0 {
|
||
cfg.Broadcast.WorkerMaxRetry = 8
|
||
}
|
||
if cfg.LuckyGiftWorker.WorkerPollInterval <= 0 {
|
||
cfg.LuckyGiftWorker.WorkerPollInterval = time.Second
|
||
}
|
||
if cfg.LuckyGiftWorker.WorkerBatchSize <= 0 {
|
||
cfg.LuckyGiftWorker.WorkerBatchSize = 100
|
||
}
|
||
if cfg.LuckyGiftWorker.WorkerConcurrency <= 0 {
|
||
cfg.LuckyGiftWorker.WorkerConcurrency = 4
|
||
}
|
||
if cfg.LuckyGiftWorker.WorkerConcurrency > cfg.LuckyGiftWorker.WorkerBatchSize {
|
||
cfg.LuckyGiftWorker.WorkerConcurrency = cfg.LuckyGiftWorker.WorkerBatchSize
|
||
}
|
||
if cfg.LuckyGiftWorker.WorkerLockTTL <= 0 {
|
||
cfg.LuckyGiftWorker.WorkerLockTTL = 30 * time.Second
|
||
}
|
||
if cfg.LuckyGiftWorker.WorkerMaxRetry <= 0 {
|
||
cfg.LuckyGiftWorker.WorkerMaxRetry = 8
|
||
}
|
||
if cfg.LuckyGiftWorker.PublishTimeout <= 0 {
|
||
cfg.LuckyGiftWorker.PublishTimeout = 5 * time.Second
|
||
}
|
||
if cfg.MessageActionConfirmWorker.OutboxPollInterval <= 0 {
|
||
cfg.MessageActionConfirmWorker.OutboxPollInterval = time.Second
|
||
}
|
||
if cfg.MessageActionConfirmWorker.OutboxBatchSize <= 0 {
|
||
cfg.MessageActionConfirmWorker.OutboxBatchSize = 100
|
||
}
|
||
if cfg.MessageActionConfirmWorker.OutboxLockTTL <= 0 {
|
||
cfg.MessageActionConfirmWorker.OutboxLockTTL = 30 * time.Second
|
||
}
|
||
if cfg.MessageActionConfirmWorker.OutboxMaxRetry <= 0 {
|
||
cfg.MessageActionConfirmWorker.OutboxMaxRetry = 8
|
||
}
|
||
if cfg.MessageActionConfirmWorker.PublishTimeout <= 0 {
|
||
cfg.MessageActionConfirmWorker.PublishTimeout = 5 * time.Second
|
||
}
|
||
cfg.UserLeaderboardWorker.RedisAddr = strings.TrimSpace(cfg.UserLeaderboardWorker.RedisAddr)
|
||
cfg.UserLeaderboardWorker.KeyPrefix = strings.TrimSpace(cfg.UserLeaderboardWorker.KeyPrefix)
|
||
rocketMQ, err := normalizeRocketMQConfig(cfg.RocketMQ)
|
||
if err != nil {
|
||
return Config{}, err
|
||
}
|
||
cfg.RocketMQ = rocketMQ
|
||
if (cfg.FirstRechargeRewardWorker.Enabled || cfg.CumulativeRechargeRewardWorker.Enabled || cfg.InviteActivityRewardWorker.Enabled || cfg.RedPacketBroadcastWorker.Enabled || cfg.UserLeaderboardWorker.Enabled) && !cfg.RocketMQ.WalletOutbox.Enabled {
|
||
return Config{}, errors.New("wallet outbox workers require rocketmq.wallet_outbox.enabled")
|
||
}
|
||
if cfg.UserLeaderboardWorker.Enabled && cfg.UserLeaderboardWorker.RedisAddr == "" {
|
||
return Config{}, errors.New("user leaderboard worker requires redis_addr")
|
||
}
|
||
if cfg.InviteActivityRewardWorker.Enabled && !cfg.RocketMQ.UserOutbox.Enabled {
|
||
return Config{}, errors.New("invite activity reward worker requires rocketmq.user_outbox.enabled")
|
||
}
|
||
if cfg.MessageActionConfirmWorker.Enabled && (!cfg.RocketMQ.UserOutbox.Enabled || !cfg.RocketMQ.MessageActionOutbox.Enabled) {
|
||
return Config{}, errors.New("message action confirm worker requires rocketmq.user_outbox.enabled and rocketmq.message_action_outbox.enabled")
|
||
}
|
||
if cfg.LuckyGiftWorker.Enabled && !cfg.TencentIM.Enabled {
|
||
return Config{}, errors.New("lucky gift worker requires tencent_im.enabled")
|
||
}
|
||
|
||
return cfg, nil
|
||
}
|
||
|
||
func normalizeRocketMQConfig(cfg RocketMQConfig) (RocketMQConfig, error) {
|
||
defaults := defaultRocketMQConfig()
|
||
cfg.NameServers = normalizeStringSlice(cfg.NameServers)
|
||
cfg.NameServerDomain = strings.TrimSpace(cfg.NameServerDomain)
|
||
cfg.AccessKey = strings.TrimSpace(cfg.AccessKey)
|
||
cfg.SecretKey = strings.TrimSpace(cfg.SecretKey)
|
||
cfg.SecurityToken = strings.TrimSpace(cfg.SecurityToken)
|
||
cfg.Namespace = strings.TrimSpace(cfg.Namespace)
|
||
if cfg.RoomOutbox.Topic = strings.TrimSpace(cfg.RoomOutbox.Topic); cfg.RoomOutbox.Topic == "" {
|
||
cfg.RoomOutbox.Topic = defaults.RoomOutbox.Topic
|
||
}
|
||
if cfg.RoomOutbox.ConsumerGroup = strings.TrimSpace(cfg.RoomOutbox.ConsumerGroup); cfg.RoomOutbox.ConsumerGroup == "" {
|
||
cfg.RoomOutbox.ConsumerGroup = defaults.RoomOutbox.ConsumerGroup
|
||
}
|
||
if cfg.RoomOutbox.ConsumerMaxReconsumeTimes <= 0 {
|
||
cfg.RoomOutbox.ConsumerMaxReconsumeTimes = defaults.RoomOutbox.ConsumerMaxReconsumeTimes
|
||
}
|
||
if cfg.WalletOutbox.Topic = strings.TrimSpace(cfg.WalletOutbox.Topic); cfg.WalletOutbox.Topic == "" {
|
||
cfg.WalletOutbox.Topic = defaults.WalletOutbox.Topic
|
||
}
|
||
cfg.WalletOutbox.RealtimeTopic = strings.TrimSpace(cfg.WalletOutbox.RealtimeTopic)
|
||
if cfg.WalletOutbox.FirstRechargeConsumerGroup = strings.TrimSpace(cfg.WalletOutbox.FirstRechargeConsumerGroup); cfg.WalletOutbox.FirstRechargeConsumerGroup == "" {
|
||
cfg.WalletOutbox.FirstRechargeConsumerGroup = defaults.WalletOutbox.FirstRechargeConsumerGroup
|
||
}
|
||
if cfg.WalletOutbox.CumulativeRechargeConsumerGroup = strings.TrimSpace(cfg.WalletOutbox.CumulativeRechargeConsumerGroup); cfg.WalletOutbox.CumulativeRechargeConsumerGroup == "" {
|
||
cfg.WalletOutbox.CumulativeRechargeConsumerGroup = defaults.WalletOutbox.CumulativeRechargeConsumerGroup
|
||
}
|
||
if cfg.WalletOutbox.InviteActivityConsumerGroup = strings.TrimSpace(cfg.WalletOutbox.InviteActivityConsumerGroup); cfg.WalletOutbox.InviteActivityConsumerGroup == "" {
|
||
cfg.WalletOutbox.InviteActivityConsumerGroup = defaults.WalletOutbox.InviteActivityConsumerGroup
|
||
}
|
||
if cfg.WalletOutbox.RedPacketBroadcastConsumerGroup = strings.TrimSpace(cfg.WalletOutbox.RedPacketBroadcastConsumerGroup); cfg.WalletOutbox.RedPacketBroadcastConsumerGroup == "" {
|
||
cfg.WalletOutbox.RedPacketBroadcastConsumerGroup = defaults.WalletOutbox.RedPacketBroadcastConsumerGroup
|
||
}
|
||
if cfg.WalletOutbox.TaskConsumerGroup = strings.TrimSpace(cfg.WalletOutbox.TaskConsumerGroup); cfg.WalletOutbox.TaskConsumerGroup == "" {
|
||
cfg.WalletOutbox.TaskConsumerGroup = defaults.WalletOutbox.TaskConsumerGroup
|
||
}
|
||
if cfg.WalletOutbox.UserLeaderboardConsumerGroup = strings.TrimSpace(cfg.WalletOutbox.UserLeaderboardConsumerGroup); cfg.WalletOutbox.UserLeaderboardConsumerGroup == "" {
|
||
cfg.WalletOutbox.UserLeaderboardConsumerGroup = defaults.WalletOutbox.UserLeaderboardConsumerGroup
|
||
}
|
||
if cfg.WalletOutbox.ConsumerMaxReconsumeTimes <= 0 {
|
||
cfg.WalletOutbox.ConsumerMaxReconsumeTimes = defaults.WalletOutbox.ConsumerMaxReconsumeTimes
|
||
}
|
||
if cfg.UserOutbox.Topic = strings.TrimSpace(cfg.UserOutbox.Topic); cfg.UserOutbox.Topic == "" {
|
||
cfg.UserOutbox.Topic = defaults.UserOutbox.Topic
|
||
}
|
||
if cfg.UserOutbox.ConsumerGroup = strings.TrimSpace(cfg.UserOutbox.ConsumerGroup); cfg.UserOutbox.ConsumerGroup == "" {
|
||
cfg.UserOutbox.ConsumerGroup = defaults.UserOutbox.ConsumerGroup
|
||
}
|
||
if cfg.UserOutbox.TaskConsumerGroup = strings.TrimSpace(cfg.UserOutbox.TaskConsumerGroup); cfg.UserOutbox.TaskConsumerGroup == "" {
|
||
cfg.UserOutbox.TaskConsumerGroup = defaults.UserOutbox.TaskConsumerGroup
|
||
}
|
||
if cfg.UserOutbox.InviteActivityConsumerGroup = strings.TrimSpace(cfg.UserOutbox.InviteActivityConsumerGroup); cfg.UserOutbox.InviteActivityConsumerGroup == "" {
|
||
cfg.UserOutbox.InviteActivityConsumerGroup = defaults.UserOutbox.InviteActivityConsumerGroup
|
||
}
|
||
if cfg.UserOutbox.MessageActionConsumerGroup = strings.TrimSpace(cfg.UserOutbox.MessageActionConsumerGroup); cfg.UserOutbox.MessageActionConsumerGroup == "" {
|
||
cfg.UserOutbox.MessageActionConsumerGroup = defaults.UserOutbox.MessageActionConsumerGroup
|
||
}
|
||
if cfg.UserOutbox.ConsumerMaxReconsumeTimes <= 0 {
|
||
cfg.UserOutbox.ConsumerMaxReconsumeTimes = defaults.UserOutbox.ConsumerMaxReconsumeTimes
|
||
}
|
||
if cfg.MessageActionOutbox.Topic = strings.TrimSpace(cfg.MessageActionOutbox.Topic); cfg.MessageActionOutbox.Topic == "" {
|
||
cfg.MessageActionOutbox.Topic = defaults.MessageActionOutbox.Topic
|
||
}
|
||
if cfg.MessageActionOutbox.ProducerGroup = strings.TrimSpace(cfg.MessageActionOutbox.ProducerGroup); cfg.MessageActionOutbox.ProducerGroup == "" {
|
||
cfg.MessageActionOutbox.ProducerGroup = defaults.MessageActionOutbox.ProducerGroup
|
||
}
|
||
if cfg.MessageActionOutbox.SendTimeout <= 0 {
|
||
cfg.MessageActionOutbox.SendTimeout = defaults.MessageActionOutbox.SendTimeout
|
||
}
|
||
if cfg.MessageActionOutbox.Retry < 0 {
|
||
cfg.MessageActionOutbox.Retry = defaults.MessageActionOutbox.Retry
|
||
}
|
||
if cfg.RoomOutbox.Enabled || cfg.WalletOutbox.Enabled || cfg.UserOutbox.Enabled || cfg.MessageActionOutbox.Enabled {
|
||
cfg.Enabled = true
|
||
}
|
||
if cfg.Enabled {
|
||
if len(cfg.NameServers) == 0 && cfg.NameServerDomain == "" {
|
||
return RocketMQConfig{}, errors.New("rocketmq name_servers or name_server_domain is required")
|
||
}
|
||
if (cfg.AccessKey == "") != (cfg.SecretKey == "") {
|
||
return RocketMQConfig{}, errors.New("rocketmq access_key and secret_key must be configured together")
|
||
}
|
||
}
|
||
return cfg, nil
|
||
}
|
||
|
||
func normalizeStringSlice(input []string) []string {
|
||
out := make([]string, 0, len(input))
|
||
for _, value := range input {
|
||
if value = strings.TrimSpace(value); value != "" {
|
||
out = append(out, value)
|
||
}
|
||
}
|
||
return out
|
||
}
|