fix(task): restore task metadata contract and type fields in task types api

This commit is contained in:
ryan
2026-08-29 12:22:51 +08:00
parent 49f9d1076f
commit ea97b64407
22 changed files with 704 additions and 133 deletions
@@ -4,6 +4,7 @@
package driver_asynq_worker
import (
"Wavelet/core/contracts"
"Wavelet/core/extpoints"
"sync"
)
@@ -28,6 +29,7 @@ type TaskMeta struct {
AsynqTask string `json:"asynq_task"`
Name string `json:"name"`
Description string `json:"description"`
Category string `json:"category,omitempty"`
SupportsTime bool `json:"supports_time"`
MaxRetry int `json:"max_retry"`
Queue string `json:"queue"`
@@ -52,16 +54,82 @@ func RegisterTaskMeta(meta TaskMeta) {
dispatchableTasks = append(dispatchableTasks, meta)
}
// GetDispatchableTasks 获取所有已注册的元数据列表(返回副本以避免并发读写冲突)
// GetDispatchableTasks 获取所有已注册的元数据列表(优先结合 activeTaskReg 和 dispatchableTasks)
func GetDispatchableTasks() []TaskMeta {
dispatchableTasksMutex.RLock()
defer dispatchableTasksMutex.RUnlock()
activeTaskRegMutex.RLock()
reg := activeTaskReg
activeTaskRegMutex.RUnlock()
var metas []TaskMeta
seen := make(map[string]bool)
if reg != nil {
for _, td := range reg.Tasks() {
dto := td.ToDTO()
m := toInternalTaskMeta(dto)
metas = append(metas, m)
seen[m.Type] = true
seen[m.AsynqTask] = true
}
}
dispatchableTasksMutex.RLock()
for _, t := range dispatchableTasks {
if !seen[t.Type] && !seen[t.AsynqTask] {
metas = append(metas, t)
seen[t.Type] = true
seen[t.AsynqTask] = true
}
}
dispatchableTasksMutex.RUnlock()
metas := make([]TaskMeta, len(dispatchableTasks))
copy(metas, dispatchableTasks)
return metas
}
func toInternalTaskMeta(dto contracts.TaskMetaDTO) TaskMeta {
params := make([]TaskParam, 0, len(dto.Params))
for _, p := range dto.Params {
params = append(params, TaskParam{
Name: p.Name,
Label: p.Label,
Type: p.Type,
Required: p.Required,
Placeholder: p.Placeholder,
Description: p.Description,
})
}
taskType := dto.Type
if taskType == "" {
taskType = dto.AsynqTask
}
if taskType == "" {
taskType = dto.Name
}
asynqTask := dto.AsynqTask
if asynqTask == "" {
asynqTask = taskType
}
name := dto.Name
if name == "" {
name = dto.DisplayName
}
if name == "" {
name = taskType
}
return TaskMeta{
Type: taskType,
AsynqTask: asynqTask,
Name: name,
Description: dto.Description,
Category: dto.Category,
SupportsTime: dto.SupportsTime,
MaxRetry: dto.MaxRetry,
Queue: dto.Queue,
Retryable: dto.Retryable,
Params: params,
}
}
var (
activeTaskRegMutex sync.RWMutex
activeTaskReg extpoints.TaskExtension
@@ -80,14 +148,10 @@ func getFromActiveTaskExtension(taskType string) *TaskMeta {
if activeTaskReg == nil {
return nil
}
if td, ok := activeTaskReg.Get(taskType); ok {
return &TaskMeta{
Type: td.Pattern,
Name: td.Pattern,
AsynqTask: td.Pattern,
Queue: "default",
Retryable: td.Retry > 0,
MaxRetry: td.Retry,
for _, td := range activeTaskReg.Tasks() {
if td.Type == taskType || td.Pattern == taskType {
m := toInternalTaskMeta(td.ToDTO())
return &m
}
}
return nil
@@ -95,9 +159,13 @@ func getFromActiveTaskExtension(taskType string) *TaskMeta {
// GetTaskMeta 根据任务类型获取元数据
func GetTaskMeta(taskType string) *TaskMeta {
if m := getFromActiveTaskExtension(taskType); m != nil {
return m
}
dispatchableTasksMutex.RLock()
for _, t := range dispatchableTasks {
if t.Type == taskType {
if t.Type == taskType || t.AsynqTask == taskType {
copied := t
dispatchableTasksMutex.RUnlock()
return &copied
@@ -105,22 +173,12 @@ func GetTaskMeta(taskType string) *TaskMeta {
}
dispatchableTasksMutex.RUnlock()
return getFromActiveTaskExtension(taskType)
return nil
}
// GetTaskMetaByAsynqTask 根据 Asynq 任务名称获取元数据
func GetTaskMetaByAsynqTask(asynqTask string) *TaskMeta {
dispatchableTasksMutex.RLock()
for _, t := range dispatchableTasks {
if t.AsynqTask == asynqTask {
copied := t
dispatchableTasksMutex.RUnlock()
return &copied
}
}
dispatchableTasksMutex.RUnlock()
return getFromActiveTaskExtension(asynqTask)
return GetTaskMeta(asynqTask)
}
// GetRegisteredAsynqTasks 返回所有已注册的 Asynq 任务名称,以便动态注册路由
@@ -330,18 +330,40 @@ func (s *taskServiceImpl) ListTasks() []contracts.TaskMetaDTO {
for _, param := range m.Params {
params = append(params, contracts.TaskParamDTO{
Name: param.Name,
Label: param.Label,
Type: param.Type,
Description: param.Description,
Placeholder: param.Placeholder,
Required: param.Required,
})
}
taskType := m.Type
if taskType == "" {
taskType = m.AsynqTask
}
if taskType == "" {
taskType = m.Name
}
asynqTask := m.AsynqTask
if asynqTask == "" {
asynqTask = taskType
}
name := m.Name
if name == "" {
name = taskType
}
res = append(res, contracts.TaskMetaDTO{
Name: m.Type,
DisplayName: m.Name,
Description: m.Description,
Params: params,
MaxRetry: m.MaxRetry,
Queue: m.Queue,
Type: taskType,
AsynqTask: asynqTask,
Name: name,
DisplayName: name,
Description: m.Description,
Category: m.Category,
SupportsTime: m.SupportsTime,
Params: params,
MaxRetry: m.MaxRetry,
Queue: m.Queue,
Retryable: m.Retryable,
})
}
return res
@@ -356,18 +378,40 @@ func (s *taskServiceImpl) GetTaskMeta(taskType string) (contracts.TaskMetaDTO, b
for _, param := range m.Params {
params = append(params, contracts.TaskParamDTO{
Name: param.Name,
Label: param.Label,
Type: param.Type,
Description: param.Description,
Placeholder: param.Placeholder,
Required: param.Required,
})
}
tType := m.Type
if tType == "" {
tType = m.AsynqTask
}
if tType == "" {
tType = m.Name
}
asynqTask := m.AsynqTask
if asynqTask == "" {
asynqTask = tType
}
name := m.Name
if name == "" {
name = tType
}
return contracts.TaskMetaDTO{
Name: m.Type,
DisplayName: m.Name,
Description: m.Description,
Params: params,
MaxRetry: m.MaxRetry,
Queue: m.Queue,
Type: tType,
AsynqTask: asynqTask,
Name: name,
DisplayName: name,
Description: m.Description,
Category: m.Category,
SupportsTime: m.SupportsTime,
Params: params,
MaxRetry: m.MaxRetry,
Queue: m.Queue,
Retryable: m.Retryable,
}, true
}
@@ -36,12 +36,7 @@ func (s *inprocTaskService) ListTasks() []contracts.TaskMetaDTO {
tasks := s.taskReg.Tasks()
res := make([]contracts.TaskMetaDTO, 0, len(tasks))
for _, td := range tasks {
res = append(res, contracts.TaskMetaDTO{
Name: td.Pattern,
DisplayName: td.Pattern,
MaxRetry: td.Retry,
Timeout: td.Timeout,
})
res = append(res, td.ToDTO())
}
return res
}
@@ -50,16 +45,12 @@ func (s *inprocTaskService) GetTaskMeta(taskType string) (contracts.TaskMetaDTO,
if s.taskReg == nil {
return contracts.TaskMetaDTO{}, false
}
td, ok := s.taskReg.Get(taskType)
if !ok {
return contracts.TaskMetaDTO{}, false
for _, td := range s.taskReg.Tasks() {
if td.Type == taskType || td.Pattern == taskType {
return td.ToDTO(), true
}
}
return contracts.TaskMetaDTO{
Name: td.Pattern,
DisplayName: td.Pattern,
MaxRetry: td.Retry,
Timeout: td.Timeout,
}, true
return contracts.TaskMetaDTO{}, false
}
func (s *inprocTaskService) ValidatePayload(_ string, payload []byte) ([]byte, error) {