mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 22:06:38 +08:00
134 lines
3.1 KiB
Go
134 lines
3.1 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Package task is a thin OpenFlare adapter over contracts.TaskService.
|
|
// Remaining OF handlers keep calling task.AppendLog / DispatchTask.
|
|
package task
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"sync"
|
|
|
|
"Wavelet/core/contracts"
|
|
|
|
"github.com/hibiken/asynq"
|
|
)
|
|
|
|
const (
|
|
// QueueDefault is the default Asynq queue name.
|
|
QueueDefault = "default"
|
|
// DefaultMaxRetry is the default max retry count for OF tasks.
|
|
DefaultMaxRetry = 3
|
|
defaultPermanentErrorMessage = "任务无法继续执行"
|
|
)
|
|
|
|
var (
|
|
svcMu sync.RWMutex
|
|
svc contracts.TaskService
|
|
)
|
|
|
|
// SetService injects the platform TaskService used by DispatchTask/AppendLog.
|
|
func SetService(s contracts.TaskService) {
|
|
svcMu.Lock()
|
|
defer svcMu.Unlock()
|
|
svc = s
|
|
}
|
|
|
|
func current() contracts.TaskService {
|
|
svcMu.RLock()
|
|
defer svcMu.RUnlock()
|
|
return svc
|
|
}
|
|
|
|
// TaskParam is the OpenFlare task parameter descriptor.
|
|
type TaskParam = contracts.TaskParamDTO
|
|
|
|
// TaskMeta is the OpenFlare task metadata descriptor.
|
|
type TaskMeta struct {
|
|
Type string
|
|
AsynqTask string
|
|
Name string
|
|
Description string
|
|
SupportsTime bool
|
|
MaxRetry int
|
|
Queue string
|
|
Retryable bool
|
|
InternalOnly bool
|
|
Params []TaskParam
|
|
}
|
|
|
|
// ToDTO converts TaskMeta to the platform DTO.
|
|
func (m TaskMeta) ToDTO() contracts.TaskMetaDTO {
|
|
queue := m.Queue
|
|
if queue == "" {
|
|
queue = QueueDefault
|
|
}
|
|
return contracts.TaskMetaDTO{
|
|
Type: m.Type,
|
|
AsynqTask: m.AsynqTask,
|
|
Name: m.Name,
|
|
DisplayName: m.Name,
|
|
Description: m.Description,
|
|
SupportsTime: m.SupportsTime,
|
|
Params: m.Params,
|
|
MaxRetry: m.MaxRetry,
|
|
Queue: queue,
|
|
Retryable: m.Retryable,
|
|
}
|
|
}
|
|
|
|
// TaskResult is the OpenFlare task execution result.
|
|
type TaskResult struct {
|
|
Message string
|
|
Detail string
|
|
}
|
|
|
|
// PayloadValidator validates and normalizes a task payload.
|
|
type PayloadValidator interface {
|
|
ValidatePayload(payload []byte) ([]byte, error)
|
|
}
|
|
|
|
// TaskHandler is the OpenFlare async task handler contract.
|
|
type TaskHandler interface {
|
|
Execute(ctx context.Context, payload []byte) (*TaskResult, error)
|
|
}
|
|
|
|
// AppendLog appends a line to the current task execution log.
|
|
func AppendLog(ctx context.Context, format string, args ...any) {
|
|
if s := current(); s != nil {
|
|
s.AppendLog(ctx, format, args...)
|
|
}
|
|
}
|
|
|
|
// DispatchTask enqueues a task by admin type.
|
|
func DispatchTask(ctx context.Context, taskType string, payload []byte, triggeredBy string) (string, error) {
|
|
s := current()
|
|
if s == nil {
|
|
return "", errors.New("task service not initialized")
|
|
}
|
|
return s.Dispatch(ctx, taskType, payload, triggeredBy)
|
|
}
|
|
|
|
type permanentTaskError struct {
|
|
message string
|
|
}
|
|
|
|
// PermanentError marks a safe domain message as a non-retryable task failure.
|
|
func PermanentError(message string) error {
|
|
message = strings.TrimSpace(message)
|
|
if message == "" {
|
|
message = defaultPermanentErrorMessage
|
|
}
|
|
return &permanentTaskError{message: message}
|
|
}
|
|
|
|
func (e *permanentTaskError) Error() string {
|
|
return e.message
|
|
}
|
|
|
|
func (e *permanentTaskError) Unwrap() error {
|
|
return asynq.SkipRetry
|
|
}
|