feat(generation): migrate article generation and template-assist to RabbitMQ queues
Replace in-process generation with queue-based async execution via RabbitMQ. Add generation task runtime for lifecycle management, article generation payload/queue abstractions, and template-assist queue publisher. Refactor prompt generation service to support batch generation with per-item error tracking. Update stream hub to bridge queue events to SSE. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -120,6 +120,8 @@ type assistJob struct {
|
||||
OutlineRequest *OutlineTaskRequest
|
||||
}
|
||||
|
||||
type AssistJob = assistJob
|
||||
|
||||
func (s *TemplateService) CreateAnalyzeTask(ctx context.Context, templateID int64, req AnalyzeTaskRequest) (*AssistTaskCreateResponse, error) {
|
||||
actor := auth.MustActor(ctx)
|
||||
|
||||
@@ -164,7 +166,7 @@ func (s *TemplateService) CreateAnalyzeTask(ctx context.Context, templateID int6
|
||||
AnalyzePrompt: extractAnalyzePromptTemplate(templateRecord.CardConfigJSON),
|
||||
AnalyzeRequest: &req,
|
||||
}
|
||||
if err := s.enqueueAssist(job); err != nil {
|
||||
if err := publishTemplateAssistTask(ctx, s.rabbitMQ, job); err != nil {
|
||||
_ = repo.FailTask(context.Background(), taskID, templateAssistTaskTypeAnalyze, actor.TenantID, err.Error(), time.Now())
|
||||
return nil, response.ErrServiceUnavailable(50312, "analyze_queue_unavailable", "analyze queue is busy, please retry")
|
||||
}
|
||||
@@ -245,7 +247,7 @@ func (s *TemplateService) CreateTitleTask(ctx context.Context, templateID int64,
|
||||
TitlePrompt: extractTitlePromptTemplate(templateRecord.CardConfigJSON),
|
||||
TitleRequest: &req,
|
||||
}
|
||||
if err := s.enqueueAssist(job); err != nil {
|
||||
if err := publishTemplateAssistTask(ctx, s.rabbitMQ, job); err != nil {
|
||||
_ = repo.FailTask(context.Background(), taskID, templateAssistTaskTypeTitle, actor.TenantID, err.Error(), time.Now())
|
||||
return nil, response.ErrServiceUnavailable(50313, "title_queue_unavailable", "title queue is busy, please retry")
|
||||
}
|
||||
@@ -326,7 +328,7 @@ func (s *TemplateService) CreateOutlineTask(ctx context.Context, templateID int6
|
||||
OutlinePrompt: extractOutlinePromptTemplate(templateRecord.CardConfigJSON),
|
||||
OutlineRequest: &req,
|
||||
}
|
||||
if err := s.enqueueAssist(job); err != nil {
|
||||
if err := publishTemplateAssistTask(ctx, s.rabbitMQ, job); err != nil {
|
||||
_ = repo.FailTask(context.Background(), taskID, templateAssistTaskTypeOutline, actor.TenantID, err.Error(), time.Now())
|
||||
return nil, response.ErrServiceUnavailable(50314, "outline_queue_unavailable", "outline queue is busy, please retry")
|
||||
}
|
||||
@@ -363,21 +365,6 @@ func (s *TemplateService) GetOutlineTask(ctx context.Context, templateID int64,
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *TemplateService) enqueueAssist(job assistJob) error {
|
||||
select {
|
||||
case s.assistJobs <- job:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("assist queue is full")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *TemplateService) runAssistWorker() {
|
||||
for job := range s.assistJobs {
|
||||
s.executeAssist(context.Background(), job)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *TemplateService) executeAssist(ctx context.Context, job assistJob) {
|
||||
repo := repository.NewTemplateAssistTaskRepository(s.pool)
|
||||
now := time.Now()
|
||||
@@ -395,6 +382,28 @@ func (s *TemplateService) executeAssist(ctx context.Context, job assistJob) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *TemplateService) ProcessQueuedAssist(ctx context.Context, job assistJob) {
|
||||
s.executeAssist(ctx, job)
|
||||
}
|
||||
|
||||
func (s *TemplateService) ProcessQueuedAssistJob(ctx context.Context, job AssistJob) {
|
||||
s.ProcessQueuedAssist(ctx, job)
|
||||
}
|
||||
|
||||
func (s *TemplateService) IsAssistTaskTerminal(ctx context.Context, job AssistJob) (bool, error) {
|
||||
record, err := repository.NewTemplateAssistTaskRepository(s.pool).GetTask(
|
||||
ctx,
|
||||
job.TaskID,
|
||||
job.TaskType,
|
||||
job.TenantID,
|
||||
job.TemplateID,
|
||||
)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return record.Status == "completed" || record.Status == "failed", nil
|
||||
}
|
||||
|
||||
func (s *TemplateService) executeAnalyzeTask(ctx context.Context, repo repository.TemplateAssistTaskRepository, job assistJob) {
|
||||
if job.AnalyzeRequest == nil {
|
||||
s.failAssist(ctx, job.TaskID, job.TaskType, job.TenantID, fmt.Errorf("missing analyze request"))
|
||||
|
||||
Reference in New Issue
Block a user