98 lines
3.0 KiB
Go
98 lines
3.0 KiB
Go
package task
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"tyapi-server/internal/domains/article/repositories"
|
|
|
|
"github.com/hibiken/asynq"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// ArticlePublisher 文章发布接口
|
|
type ArticlePublisher interface {
|
|
PublishArticleByID(ctx context.Context, articleID string) error
|
|
}
|
|
|
|
// ArticleTaskHandler 文章任务处理器
|
|
type ArticleTaskHandler struct {
|
|
publisher ArticlePublisher
|
|
scheduledTaskRepo repositories.ScheduledTaskRepository
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewArticleTaskHandler 创建文章任务处理器
|
|
func NewArticleTaskHandler(
|
|
publisher ArticlePublisher,
|
|
scheduledTaskRepo repositories.ScheduledTaskRepository,
|
|
logger *zap.Logger,
|
|
) *ArticleTaskHandler {
|
|
return &ArticleTaskHandler{
|
|
publisher: publisher,
|
|
scheduledTaskRepo: scheduledTaskRepo,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// HandleArticlePublish 处理文章定时发布任务
|
|
func (h *ArticleTaskHandler) HandleArticlePublish(ctx context.Context, t *asynq.Task) error {
|
|
var payload map[string]interface{}
|
|
if err := json.Unmarshal(t.Payload(), &payload); err != nil {
|
|
h.logger.Error("解析任务载荷失败", zap.Error(err))
|
|
return fmt.Errorf("解析任务载荷失败: %w", err)
|
|
}
|
|
|
|
articleID, ok := payload["article_id"].(string)
|
|
if !ok {
|
|
h.logger.Error("任务载荷中缺少文章ID")
|
|
return fmt.Errorf("任务载荷中缺少文章ID")
|
|
}
|
|
|
|
// 获取任务状态记录
|
|
task, err := h.scheduledTaskRepo.GetByTaskID(ctx, t.ResultWriter().TaskID())
|
|
if err != nil {
|
|
h.logger.Error("获取任务状态记录失败", zap.String("task_id", t.ResultWriter().TaskID()), zap.Error(err))
|
|
// 继续执行,不阻断任务
|
|
} else {
|
|
// 检查任务是否已取消
|
|
if task.IsCancelled() {
|
|
h.logger.Info("任务已取消,跳过执行", zap.String("task_id", t.ResultWriter().TaskID()))
|
|
return nil
|
|
}
|
|
|
|
// 标记任务为正在执行
|
|
task.MarkAsRunning()
|
|
if err := h.scheduledTaskRepo.Update(ctx, task); err != nil {
|
|
h.logger.Warn("更新任务状态失败", zap.String("task_id", t.ResultWriter().TaskID()), zap.Error(err))
|
|
}
|
|
}
|
|
|
|
// 执行文章发布
|
|
if err := h.publisher.PublishArticleByID(ctx, articleID); err != nil {
|
|
// 更新任务状态为失败
|
|
if task.ID != "" {
|
|
task.MarkAsFailed(err.Error())
|
|
if updateErr := h.scheduledTaskRepo.Update(ctx, task); updateErr != nil {
|
|
h.logger.Warn("更新任务失败状态失败", zap.String("task_id", t.ResultWriter().TaskID()), zap.Error(updateErr))
|
|
}
|
|
}
|
|
|
|
h.logger.Error("定时发布文章失败",
|
|
zap.String("article_id", articleID),
|
|
zap.Error(err))
|
|
return fmt.Errorf("定时发布文章失败: %w", err)
|
|
}
|
|
|
|
// 更新任务状态为已完成
|
|
if task.ID != "" {
|
|
task.MarkAsCompleted()
|
|
if err := h.scheduledTaskRepo.Update(ctx, task); err != nil {
|
|
h.logger.Warn("更新任务完成状态失败", zap.String("task_id", t.ResultWriter().TaskID()), zap.Error(err))
|
|
}
|
|
}
|
|
|
|
h.logger.Info("定时发布文章成功", zap.String("article_id", articleID))
|
|
return nil
|
|
}
|