This commit is contained in:
@@ -8,7 +8,7 @@ type GetPollingConcurrencyReq struct {
|
||||
// UpdatePollingConcurrencyReq 更新轮询并发配置请求
|
||||
type UpdatePollingConcurrencyReq struct {
|
||||
TaskType string `path:"task_type" description:"任务类型" required:"true"`
|
||||
MaxConcurrency int `json:"max_concurrency" validate:"required,min=1,max=1000" description:"最大并发数(1-1000)"`
|
||||
MaxConcurrency int `json:"max_concurrency" validate:"required,min=1" description:"最大并发数(正整数)"`
|
||||
}
|
||||
|
||||
// PollingConcurrencyResp 轮询并发配置响应
|
||||
|
||||
@@ -33,7 +33,7 @@ func (PollingConfig) TableName() string {
|
||||
// PollingConcurrencyConfig 并发控制配置表
|
||||
type PollingConcurrencyConfig struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||||
TaskType string `gorm:"column:task_type;type:varchar(50);uniqueIndex;not null;comment:任务类型:realname/carddata/package/stop_start" json:"task_type"`
|
||||
TaskType string `gorm:"column:task_type;type:varchar(50);uniqueIndex;not null;comment:任务类型:realname/carddata/package/protect/card_status" json:"task_type"`
|
||||
MaxConcurrency int `gorm:"column:max_concurrency;not null;default:50;comment:最大并发数" json:"max_concurrency"`
|
||||
Description string `gorm:"column:description;type:text;comment:配置说明" json:"description"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"`
|
||||
|
||||
@@ -69,6 +69,9 @@ func (s *ConcurrencyService) List(ctx context.Context) ([]*ConcurrencyStatus, er
|
||||
if err != nil && err != redis.Nil {
|
||||
current = 0
|
||||
}
|
||||
if current < 0 {
|
||||
current = 0
|
||||
}
|
||||
|
||||
status.Current = current
|
||||
status.Available = int64(cfg.MaxConcurrency) - current
|
||||
@@ -104,6 +107,9 @@ func (s *ConcurrencyService) GetByTaskType(ctx context.Context, taskType string)
|
||||
if err != nil && err != redis.Nil {
|
||||
current = 0
|
||||
}
|
||||
if current < 0 {
|
||||
current = 0
|
||||
}
|
||||
|
||||
status.Current = current
|
||||
status.Available = int64(cfg.MaxConcurrency) - current
|
||||
@@ -120,8 +126,8 @@ func (s *ConcurrencyService) GetByTaskType(ctx context.Context, taskType string)
|
||||
// UpdateMaxConcurrency 更新最大并发数
|
||||
func (s *ConcurrencyService) UpdateMaxConcurrency(ctx context.Context, taskType string, maxConcurrency int, updatedBy uint) error {
|
||||
// 验证参数
|
||||
if maxConcurrency < 1 || maxConcurrency > 1000 {
|
||||
return errors.New(errors.CodeInvalidParam, "并发数必须在 1-1000 之间")
|
||||
if maxConcurrency < 1 {
|
||||
return errors.New(errors.CodeInvalidParam, "并发数必须为正整数")
|
||||
}
|
||||
|
||||
// 验证任务类型存在
|
||||
@@ -248,6 +254,7 @@ func (s *ConcurrencyService) InitFromDB(ctx context.Context) error {
|
||||
continue
|
||||
}
|
||||
}
|
||||
_ = s.redis.Del(ctx, constants.RedisPollingConcurrencyConfigKey("stop_start")).Err()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -269,12 +276,16 @@ func pollingConcurrencyCurrentKey(taskType string) string {
|
||||
// getTaskTypeName 获取任务类型的中文名称
|
||||
func (s *ConcurrencyService) getTaskTypeName(taskType string) string {
|
||||
switch taskType {
|
||||
case constants.TaskTypePollingRealname:
|
||||
case "realname":
|
||||
return "实名检查"
|
||||
case constants.TaskTypePollingCarddata:
|
||||
case "carddata":
|
||||
return "流量检查"
|
||||
case constants.TaskTypePollingPackage:
|
||||
case "package":
|
||||
return "套餐检查"
|
||||
case "protect":
|
||||
return "保护期检查"
|
||||
case "card_status":
|
||||
return "卡状态检查"
|
||||
default:
|
||||
return taskType
|
||||
}
|
||||
|
||||
@@ -29,6 +29,17 @@ var acquireConcurrencyScript = redis.NewScript(`
|
||||
return current
|
||||
`)
|
||||
|
||||
var releaseConcurrencyScript = redis.NewScript(`
|
||||
local current = tonumber(redis.call('GET', KEYS[1]) or '0') or 0
|
||||
if current <= 0 then
|
||||
if redis.call('EXISTS', KEYS[1]) == 1 then
|
||||
redis.call('SET', KEYS[1], 0, 'KEEPTTL')
|
||||
end
|
||||
return 0
|
||||
end
|
||||
return redis.call('DECR', KEYS[1])
|
||||
`)
|
||||
|
||||
const pollingFallbackOperationTimeout = 5 * time.Second
|
||||
|
||||
// pollingFallbackContext 创建轮询兜底操作使用的独立短超时上下文。
|
||||
@@ -101,7 +112,7 @@ func (b *PollingBase) releaseConcurrency(_ context.Context, taskType string) {
|
||||
defer cancel()
|
||||
|
||||
currentKey := constants.RedisPollingConcurrencyCurrentKey(taskType)
|
||||
if err := b.redis.Decr(ctx, currentKey).Err(); err != nil {
|
||||
if err := releaseConcurrencyScript.Run(ctx, b.redis, []string{currentKey}).Err(); err != nil {
|
||||
b.logger.Warn("释放并发计数失败", zap.String("task_type", taskType), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user