优化结构
This commit is contained in:
@@ -14,27 +14,19 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz/system"
|
||||
taskbiz "kra/internal/biz/task"
|
||||
"kra/internal/conf"
|
||||
)
|
||||
|
||||
type TaskExecutor struct {
|
||||
tasks *taskbiz.TaskUsecase
|
||||
media *system.MediaUsecase
|
||||
runtime *conf.Runtime
|
||||
methods taskbiz.TaskMethodRegistry
|
||||
}
|
||||
|
||||
func NewTaskExecutor(tasks *taskbiz.TaskUsecase, media *system.MediaUsecase, runtime *conf.Runtime) *TaskExecutor {
|
||||
return NewTaskExecutorWithRegistry(tasks, media, runtime, taskbiz.DefaultTaskMethodRegistry())
|
||||
}
|
||||
|
||||
func NewTaskExecutorWithRegistry(tasks *taskbiz.TaskUsecase, media *system.MediaUsecase, runtime *conf.Runtime, methods taskbiz.TaskMethodRegistry) *TaskExecutor {
|
||||
func NewTaskExecutorWithRegistry(tasks *taskbiz.TaskUsecase, methods taskbiz.TaskMethodRegistry) *TaskExecutor {
|
||||
if methods == nil {
|
||||
methods = taskbiz.DefaultTaskMethodRegistry()
|
||||
}
|
||||
return &TaskExecutor{tasks: tasks, media: media, runtime: runtime, methods: methods}
|
||||
return &TaskExecutor{tasks: tasks, methods: methods}
|
||||
}
|
||||
|
||||
func privateIP(ip net.IP) bool {
|
||||
@@ -63,6 +55,12 @@ func taskHTTPClient(allowPrivate bool) *http.Client {
|
||||
}
|
||||
|
||||
func (e *TaskExecutor) runHTTP(ctx context.Context, task *taskbiz.TimedTask) (string, error) {
|
||||
if task == nil {
|
||||
return "", errors.New("任务不能为空")
|
||||
}
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
parsed, err := url.Parse(task.HTTPURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("URL 非法: %w", err)
|
||||
@@ -70,6 +68,9 @@ func (e *TaskExecutor) runHTTP(ctx context.Context, task *taskbiz.TimedTask) (st
|
||||
if parsed.Scheme != "http" && parsed.Scheme != "https" {
|
||||
return "", fmt.Errorf("仅允许 http/https, 实际为 %q", parsed.Scheme)
|
||||
}
|
||||
if parsed.Host == "" {
|
||||
return "", errors.New("URL 缺少主机名")
|
||||
}
|
||||
method := strings.ToUpper(strings.TrimSpace(task.HTTPMethod))
|
||||
if method == "" {
|
||||
method = http.MethodGet
|
||||
@@ -83,6 +84,9 @@ func (e *TaskExecutor) runHTTP(ctx context.Context, task *taskbiz.TimedTask) (st
|
||||
if err = json.Unmarshal(task.HTTPHeader, &headers); err != nil {
|
||||
return "", fmt.Errorf("http_header 必须是 JSON 对象: %w", err)
|
||||
}
|
||||
if headers == nil {
|
||||
return "", errors.New("http_header 必须是 JSON 对象")
|
||||
}
|
||||
}
|
||||
for key, value := range headers {
|
||||
request.Header.Set(key, value)
|
||||
@@ -92,8 +96,11 @@ func (e *TaskExecutor) runHTTP(ctx context.Context, task *taskbiz.TimedTask) (st
|
||||
return "", err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
body, _ := io.ReadAll(io.LimitReader(response.Body, 1<<20))
|
||||
body, readErr := io.ReadAll(io.LimitReader(response.Body, 1<<20))
|
||||
output := fmt.Sprintf("HTTP %d: %s", response.StatusCode, string(body))
|
||||
if readErr != nil {
|
||||
return output, fmt.Errorf("读取 HTTP 响应失败: %w", readErr)
|
||||
}
|
||||
if response.StatusCode < 200 || response.StatusCode >= 300 {
|
||||
return output, fmt.Errorf("非 2xx 响应: %d", response.StatusCode)
|
||||
}
|
||||
@@ -110,7 +117,24 @@ func truncateTaskText(value string) string {
|
||||
return value[:limit] + "...(截断)"
|
||||
}
|
||||
|
||||
func (e *TaskExecutor) recordTaskLog(ctx context.Context, log *taskbiz.TimedTaskLog) {
|
||||
defer func() { _ = recover() }()
|
||||
if e == nil || e.tasks == nil || log == nil {
|
||||
return
|
||||
}
|
||||
_ = e.tasks.RecordTaskLog(ctx, log)
|
||||
}
|
||||
|
||||
func (e *TaskExecutor) runMethod(ctx context.Context, task *taskbiz.TimedTask) error {
|
||||
if task == nil {
|
||||
return errors.New("任务不能为空")
|
||||
}
|
||||
if e == nil {
|
||||
return errors.New("任务执行器未初始化")
|
||||
}
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
var method taskbiz.TaskMethodFunc
|
||||
var ok bool
|
||||
if e.methods != nil {
|
||||
@@ -151,7 +175,11 @@ func (e *TaskExecutor) Run(ctx context.Context, task *taskbiz.TimedTask, trigger
|
||||
ctx = context.Background()
|
||||
}
|
||||
started := time.Now()
|
||||
log = &taskbiz.TimedTaskLog{TaskID: task.ID, TaskName: task.Name, TriggerType: trigger, StartedAt: started, Status: "success"}
|
||||
log = &taskbiz.TimedTaskLog{TriggerType: trigger, StartedAt: started, Status: "success"}
|
||||
if task != nil {
|
||||
log.TaskID = task.ID
|
||||
log.TaskName = task.Name
|
||||
}
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
log.Status = "fail"
|
||||
@@ -162,8 +190,20 @@ func (e *TaskExecutor) Run(ctx context.Context, task *taskbiz.TimedTask, trigger
|
||||
log.DurationMS = log.FinishedAt.Sub(started).Milliseconds()
|
||||
logCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 3*time.Second)
|
||||
defer cancel()
|
||||
_ = e.tasks.RecordTaskLog(logCtx, log)
|
||||
if task != nil {
|
||||
e.recordTaskLog(logCtx, log)
|
||||
}
|
||||
}()
|
||||
if task == nil {
|
||||
log.Status = "fail"
|
||||
log.ErrorMsg = "任务不能为空"
|
||||
return log
|
||||
}
|
||||
if e == nil {
|
||||
log.Status = "fail"
|
||||
log.ErrorMsg = "任务执行器未初始化"
|
||||
return log
|
||||
}
|
||||
var err error
|
||||
switch task.ExecutorType {
|
||||
case taskbiz.TaskExecutorMethod:
|
||||
|
||||
Reference in New Issue
Block a user