request->getGet('status') ?? ''); $jobs = model(JobModel::class)->orderBy('created_at', 'DESC')->limit(100); if ($status !== '' && in_array($status, ['queued', 'processing', 'completed', 'failed', 'cancelled', 'expired'], true)) { $jobs->where('status', $status); } return $this->render('jobs_index', [ 'jobs' => $jobs->findAll(), 'filter' => $status, 'counts' => [ 'queued' => model(JobModel::class)->countQueued(), 'processing' => model(JobModel::class)->countProcessing(), 'failed' => model(JobModel::class)->where('status', 'failed')->countAllResults(), 'completed' => model(JobModel::class)->where('status', 'completed')->countAllResults(), ], ]); } public function retry(string $id): ResponseInterface { $job = model(JobModel::class)->find($id); if ($job === null) { throw new \CodeIgniter\Exceptions\PageNotFoundException(); } Pipeline::failJob($id, 'superseded by retry'); $clone = $job; $clone['status'] = 'queued'; $clone['stage'] = 'queued'; $clone['progress'] = 0; $clone['attempts'] = 0; $clone['error'] = null; $clone['output_file'] = null; $clone['output_size'] = 0; $clone['created_at'] = gmdate('Y-m-d H:i:s'); $clone['started_at'] = null; $clone['completed_at'] = null; $clone['expires_at'] = gmdate('Y-m-d H:i:s', time() + config('Site')->retentionHours * 3600); unset($clone['id']); model(JobModel::class)->insert($clone, false); return redirect()->to('/admin/jobs'); } }