This commit is contained in:
@@ -17,17 +17,24 @@ import (
|
||||
|
||||
// ArticleTaskHandler 文章任务处理器
|
||||
type ArticleTaskHandler struct {
|
||||
logger *zap.Logger
|
||||
articleApplicationService article.ArticleApplicationService
|
||||
asyncTaskRepo repositories.AsyncTaskRepository
|
||||
logger *zap.Logger
|
||||
articleApplicationService article.ArticleApplicationService
|
||||
announcementApplicationService article.AnnouncementApplicationService
|
||||
asyncTaskRepo repositories.AsyncTaskRepository
|
||||
}
|
||||
|
||||
// NewArticleTaskHandler 创建文章任务处理器
|
||||
func NewArticleTaskHandler(logger *zap.Logger, articleApplicationService article.ArticleApplicationService, asyncTaskRepo repositories.AsyncTaskRepository) *ArticleTaskHandler {
|
||||
func NewArticleTaskHandler(
|
||||
logger *zap.Logger,
|
||||
articleApplicationService article.ArticleApplicationService,
|
||||
announcementApplicationService article.AnnouncementApplicationService,
|
||||
asyncTaskRepo repositories.AsyncTaskRepository,
|
||||
) *ArticleTaskHandler {
|
||||
return &ArticleTaskHandler{
|
||||
logger: logger,
|
||||
articleApplicationService: articleApplicationService,
|
||||
asyncTaskRepo: asyncTaskRepo,
|
||||
logger: logger,
|
||||
articleApplicationService: articleApplicationService,
|
||||
announcementApplicationService: announcementApplicationService,
|
||||
asyncTaskRepo: asyncTaskRepo,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +119,47 @@ func (h *ArticleTaskHandler) HandleArticleModify(ctx context.Context, t *asynq.T
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandleAnnouncementPublish 处理公告发布任务
|
||||
func (h *ArticleTaskHandler) HandleAnnouncementPublish(ctx context.Context, t *asynq.Task) error {
|
||||
h.logger.Info("开始处理公告发布任务")
|
||||
|
||||
var payload AnnouncementPublishPayload
|
||||
if err := json.Unmarshal(t.Payload(), &payload); err != nil {
|
||||
h.logger.Error("解析公告发布任务载荷失败", zap.Error(err))
|
||||
h.updateTaskStatus(ctx, t, "failed", "解析任务载荷失败")
|
||||
return err
|
||||
}
|
||||
|
||||
h.logger.Info("处理公告发布任务",
|
||||
zap.String("announcement_id", payload.AnnouncementID),
|
||||
zap.Time("publish_at", payload.PublishAt))
|
||||
|
||||
// 检查任务是否已被取消
|
||||
if err := h.checkTaskStatus(ctx, t); err != nil {
|
||||
h.logger.Info("任务已被取消,跳过执行", zap.String("announcement_id", payload.AnnouncementID))
|
||||
return nil // 静默返回,不报错
|
||||
}
|
||||
|
||||
// 调用公告应用服务发布公告
|
||||
if h.announcementApplicationService != nil {
|
||||
err := h.announcementApplicationService.PublishAnnouncementByID(ctx, payload.AnnouncementID)
|
||||
if err != nil {
|
||||
h.logger.Error("公告发布失败", zap.String("announcement_id", payload.AnnouncementID), zap.Error(err))
|
||||
h.updateTaskStatus(ctx, t, "failed", "公告发布失败: "+err.Error())
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
h.logger.Warn("公告应用服务未初始化,跳过发布", zap.String("announcement_id", payload.AnnouncementID))
|
||||
h.updateTaskStatus(ctx, t, "failed", "公告应用服务未初始化")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 更新任务状态为成功
|
||||
h.updateTaskStatus(ctx, t, "completed", "")
|
||||
h.logger.Info("公告发布任务处理完成", zap.String("announcement_id", payload.AnnouncementID))
|
||||
return nil
|
||||
}
|
||||
|
||||
// ArticlePublishPayload 文章发布任务载荷
|
||||
type ArticlePublishPayload struct {
|
||||
ArticleID string `json:"article_id"`
|
||||
@@ -157,9 +205,9 @@ func (p *ArticleCancelPayload) FromJSON(data []byte) error {
|
||||
|
||||
// ArticleModifyPayload 文章修改任务载荷
|
||||
type ArticleModifyPayload struct {
|
||||
ArticleID string `json:"article_id"`
|
||||
NewPublishAt time.Time `json:"new_publish_at"`
|
||||
UserID string `json:"user_id"`
|
||||
ArticleID string `json:"article_id"`
|
||||
NewPublishAt time.Time `json:"new_publish_at"`
|
||||
UserID string `json:"user_id"`
|
||||
}
|
||||
|
||||
// GetType 获取任务类型
|
||||
@@ -177,6 +225,28 @@ func (p *ArticleModifyPayload) FromJSON(data []byte) error {
|
||||
return json.Unmarshal(data, p)
|
||||
}
|
||||
|
||||
// AnnouncementPublishPayload 公告发布任务载荷
|
||||
type AnnouncementPublishPayload struct {
|
||||
AnnouncementID string `json:"announcement_id"`
|
||||
PublishAt time.Time `json:"publish_at"`
|
||||
UserID string `json:"user_id"`
|
||||
}
|
||||
|
||||
// GetType 获取任务类型
|
||||
func (p *AnnouncementPublishPayload) GetType() types.TaskType {
|
||||
return types.TaskTypeAnnouncementPublish
|
||||
}
|
||||
|
||||
// ToJSON 序列化为JSON
|
||||
func (p *AnnouncementPublishPayload) ToJSON() ([]byte, error) {
|
||||
return json.Marshal(p)
|
||||
}
|
||||
|
||||
// FromJSON 从JSON反序列化
|
||||
func (p *AnnouncementPublishPayload) FromJSON(data []byte) error {
|
||||
return json.Unmarshal(data, p)
|
||||
}
|
||||
|
||||
// updateTaskStatus 更新任务状态
|
||||
func (h *ArticleTaskHandler) updateTaskStatus(ctx context.Context, t *asynq.Task, status string, errorMsg string) {
|
||||
// 从任务载荷中提取任务ID
|
||||
@@ -189,9 +259,11 @@ func (h *ArticleTaskHandler) updateTaskStatus(ctx context.Context, t *asynq.Task
|
||||
// 尝试从payload中获取任务ID
|
||||
taskID, ok := payload["task_id"].(string)
|
||||
if !ok {
|
||||
// 如果没有task_id,尝试从article_id生成
|
||||
// 如果没有task_id,尝试从article_id或announcement_id生成
|
||||
if articleID, ok := payload["article_id"].(string); ok {
|
||||
taskID = fmt.Sprintf("article-publish-%s", articleID)
|
||||
} else if announcementID, ok := payload["announcement_id"].(string); ok {
|
||||
taskID = fmt.Sprintf("announcement-publish-%s", announcementID)
|
||||
} else {
|
||||
h.logger.Error("无法从任务载荷中获取任务ID")
|
||||
return
|
||||
@@ -205,7 +277,7 @@ func (h *ArticleTaskHandler) updateTaskStatus(ctx context.Context, t *asynq.Task
|
||||
} else if status == "completed" {
|
||||
// 成功时:清除错误信息并更新状态
|
||||
if err := h.asyncTaskRepo.UpdateStatusWithSuccess(ctx, taskID, entities.TaskStatus(status)); err != nil {
|
||||
h.logger.Error("更新任务状态失败",
|
||||
h.logger.Error("更新任务状态失败",
|
||||
zap.String("task_id", taskID),
|
||||
zap.String("status", status),
|
||||
zap.Error(err))
|
||||
@@ -213,14 +285,14 @@ func (h *ArticleTaskHandler) updateTaskStatus(ctx context.Context, t *asynq.Task
|
||||
} else {
|
||||
// 其他状态:只更新状态
|
||||
if err := h.asyncTaskRepo.UpdateStatus(ctx, taskID, entities.TaskStatus(status)); err != nil {
|
||||
h.logger.Error("更新任务状态失败",
|
||||
h.logger.Error("更新任务状态失败",
|
||||
zap.String("task_id", taskID),
|
||||
zap.String("status", status),
|
||||
zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
h.logger.Info("任务状态已更新",
|
||||
h.logger.Info("任务状态已更新",
|
||||
zap.String("task_id", taskID),
|
||||
zap.String("status", status),
|
||||
zap.String("error_msg", errorMsg))
|
||||
@@ -237,29 +309,29 @@ func (h *ArticleTaskHandler) handleTaskFailure(ctx context.Context, taskID strin
|
||||
|
||||
// 增加重试次数
|
||||
newRetryCount := task.RetryCount + 1
|
||||
|
||||
|
||||
// 检查是否达到最大重试次数
|
||||
if newRetryCount >= task.MaxRetries {
|
||||
// 达到最大重试次数,标记为最终失败
|
||||
if err := h.asyncTaskRepo.UpdateStatusWithRetryAndError(ctx, taskID, entities.TaskStatusFailed, errorMsg); err != nil {
|
||||
h.logger.Error("更新任务状态失败",
|
||||
h.logger.Error("更新任务状态失败",
|
||||
zap.String("task_id", taskID),
|
||||
zap.String("status", "failed"),
|
||||
zap.Error(err))
|
||||
}
|
||||
h.logger.Info("任务最终失败,已达到最大重试次数",
|
||||
h.logger.Info("任务最终失败,已达到最大重试次数",
|
||||
zap.String("task_id", taskID),
|
||||
zap.Int("retry_count", newRetryCount),
|
||||
zap.Int("max_retries", task.MaxRetries))
|
||||
} else {
|
||||
// 未达到最大重试次数,保持pending状态,记录错误信息
|
||||
if err := h.asyncTaskRepo.UpdateRetryCountAndError(ctx, taskID, newRetryCount, errorMsg); err != nil {
|
||||
h.logger.Error("更新任务重试次数失败",
|
||||
h.logger.Error("更新任务重试次数失败",
|
||||
zap.String("task_id", taskID),
|
||||
zap.Int("retry_count", newRetryCount),
|
||||
zap.Error(err))
|
||||
}
|
||||
h.logger.Info("任务失败,准备重试",
|
||||
h.logger.Info("任务失败,准备重试",
|
||||
zap.String("task_id", taskID),
|
||||
zap.Int("retry_count", newRetryCount),
|
||||
zap.Int("max_retries", task.MaxRetries))
|
||||
@@ -278,9 +350,11 @@ func (h *ArticleTaskHandler) checkTaskStatus(ctx context.Context, t *asynq.Task)
|
||||
// 尝试从payload中获取任务ID
|
||||
taskID, ok := payload["task_id"].(string)
|
||||
if !ok {
|
||||
// 如果没有task_id,尝试从article_id生成
|
||||
// 如果没有task_id,尝试从article_id或announcement_id生成
|
||||
if articleID, ok := payload["article_id"].(string); ok {
|
||||
taskID = fmt.Sprintf("article-publish-%s", articleID)
|
||||
} else if announcementID, ok := payload["announcement_id"].(string); ok {
|
||||
taskID = fmt.Sprintf("announcement-publish-%s", announcementID)
|
||||
} else {
|
||||
h.logger.Error("无法从任务载荷中获取任务ID")
|
||||
return fmt.Errorf("无法获取任务ID")
|
||||
@@ -301,4 +375,4 @@ func (h *ArticleTaskHandler) checkTaskStatus(ctx context.Context, t *asynq.Task)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user