| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- <?php
- namespace App\Jobs;
- use App\Services\ExamAnswerAnalysisService;
- use App\Services\TaskManager;
- use Illuminate\Bus\Queueable;
- use Illuminate\Contracts\Queue\ShouldQueue;
- use Illuminate\Foundation\Bus\Dispatchable;
- use Illuminate\Queue\InteractsWithQueue;
- use Illuminate\Queue\SerializesModels;
- use Illuminate\Support\Facades\Log;
- use Throwable;
- class ProcessExamAnswerAnalysisJob implements ShouldQueue
- {
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- public int $tries = 2;
- public int $timeout = 300;
- public array $backoff = [5, 15];
- /**
- * @param array<string,mixed> $examData
- */
- public function __construct(
- public string $taskId,
- public array $examData
- ) {
- // Keep the default on the scaled worker fleet. In production today the
- // PDF nodes are the only horizontally scaled queue consumers.
- $this->onQueue((string) config('queue.workloads.exam_answer_analysis', 'pdf'));
- $this->afterCommit();
- }
- public function handle(ExamAnswerAnalysisService $analysisService, TaskManager $taskManager): void
- {
- try {
- $taskManager->updateTaskProgress($this->taskId, 10, '正在分析考试答题...');
- Log::warning('ProcessExamAnswerAnalysisJob: 开始处理考试答题分析', [
- 'task_id' => $this->taskId,
- 'paper_id' => $this->examData['paper_id'] ?? null,
- 'student_id' => $this->examData['student_id'] ?? null,
- 'question_count' => count($this->examData['questions'] ?? []),
- 'attempt' => $this->attempts(),
- 'memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
- ]);
- $result = $analysisService->analyzeExamAnswers($this->examData);
- $taskManager->markTaskCompleted($this->taskId, [
- 'paper_id' => $this->examData['paper_id'] ?? null,
- 'student_id' => $this->examData['student_id'] ?? null,
- 'analysis_status' => 'completed',
- 'pdf_status' => 'queued',
- 'analyzed_knowledge_points' => count($result['knowledge_point_analysis'] ?? []),
- 'result_url' => isset($this->examData['student_id'], $this->examData['paper_id'])
- ? route('api.exam-answer-analysis.result', [
- 'student_id' => $this->examData['student_id'],
- 'paper_id' => $this->examData['paper_id'],
- ])
- : null,
- 'pdf_lookup_url' => isset($this->examData['paper_id'])
- ? route('api.exam-analysis.pdf', ['paper_id' => $this->examData['paper_id']])
- : null,
- ]);
- $taskManager->sendCallback($this->taskId);
- Log::warning('ProcessExamAnswerAnalysisJob: 考试答题分析完成', [
- 'task_id' => $this->taskId,
- 'paper_id' => $this->examData['paper_id'] ?? null,
- 'student_id' => $this->examData['student_id'] ?? null,
- 'memory_peak_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
- ]);
- } catch (Throwable $e) {
- $taskManager->markTaskFailed($this->taskId, $e->getMessage());
- $taskManager->sendCallback($this->taskId);
- Log::error('ProcessExamAnswerAnalysisJob: 考试答题分析失败', [
- 'task_id' => $this->taskId,
- 'paper_id' => $this->examData['paper_id'] ?? null,
- 'student_id' => $this->examData['student_id'] ?? null,
- 'error' => $e->getMessage(),
- 'exception' => get_class($e),
- 'memory_peak_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
- ]);
- throw $e;
- }
- }
- public function failed(Throwable $exception): void
- {
- Log::error('ProcessExamAnswerAnalysisJob: 队列任务最终失败', [
- 'task_id' => $this->taskId,
- 'paper_id' => $this->examData['paper_id'] ?? null,
- 'student_id' => $this->examData['student_id'] ?? null,
- 'error' => $exception->getMessage(),
- ]);
- }
- }
|