Skip to content

Commit 50d88c2

Browse files
committed
Rewrite failed-jobs command
1 parent e8f7864 commit 50d88c2

File tree

1 file changed

+67
-34
lines changed

1 file changed

+67
-34
lines changed

src/Console/Commands/FailedJobs.php

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,67 +16,100 @@ class FailedJobs extends Command implements Isolatable, PromptsForMissingInput
1616
/**
1717
* @var string
1818
*/
19-
protected $signature = 'codebarista:failed-jobs';
19+
protected $signature = 'codebarista:failed-jobs {action}';
2020

2121
/**
2222
* @var string
2323
*/
24-
protected $description = 'Retry or delete failed jobs';
24+
protected $description = 'Retry, delete or reset failed jobs';
25+
26+
protected function promptForMissingArgumentsUsing(): array
27+
{
28+
return [
29+
'action' => ['Which action should be executed?', 'retry, delete or reset'],
30+
];
31+
}
2532

2633
public function handle(RedisJobRepository $repository): int
2734
{
28-
$action = $this->choice('What action should be taken?', [
29-
'delete',
30-
'retry',
31-
]);
32-
33-
return match ($action) {
34-
'delete' => $this->deleteFailedJobs($repository),
35-
'retry' => $this->retryFailedJobs($repository),
35+
$amount = $repository->totalFailed();
36+
37+
return match ($this->argument('action')) {
38+
'delete' => $this->deleteFailedJobs($repository, $amount),
39+
'retry' => $this->retryFailedJobs($repository, $amount),
40+
'reset' => $this->resetFailedJobs($repository),
3641
default => self::INVALID,
3742
};
43+
3844
}
3945

40-
private function deleteFailedJobs(RedisJobRepository $repository): int
46+
private function deleteFailedJobs(RedisJobRepository $repository, int $amount): int
4147
{
42-
if (! $this->confirm('Really delete all failed jobs?')) {
43-
$this->components->info('Process terminated by user');
48+
if ($this->confirm(sprintf('Really delete %d failed %s?', $amount, Str::plural('job', $amount)))) {
49+
$failedJobs = $this->getFailedJobs($repository, $amount);
50+
$counter = 0;
4451

45-
return self::SUCCESS;
52+
foreach ($failedJobs as $jobId) {
53+
$counter += $repository->deleteFailed($jobId);
54+
}
55+
56+
$this->resetFailedJobs($repository);
57+
58+
$this->components->info(sprintf('%d of %d %s deleted.',
59+
$counter, $amount, Str::plural('failed job', $amount)
60+
));
4661
}
4762

48-
$i = $repository->getFailed()->count();
63+
return self::SUCCESS;
64+
}
65+
66+
private function retryFailedJobs(RedisJobRepository $repository, int $amount): int
67+
{
68+
$chunk = (int) $this->ask('How many failed jobs should be retried at once?', $amount);
4969

50-
// What a hack...but it works
51-
$repository->recentFailedJobExpires = 0;
52-
$repository->trimRecentJobs();
70+
$failedJobs = $this->getFailedJobs($repository, $chunk);
71+
$counter = 0;
5372

54-
$repository->failedJobExpires = 0;
55-
$repository->trimFailedJobs();
73+
foreach ($failedJobs as $jobId) {
74+
dispatch(new RetryFailedJob($jobId));
75+
$counter += $repository->deleteFailed($jobId);
76+
}
5677

57-
$this->components->info(
58-
sprintf('%d %s deleted.', $i, Str::plural(' job', $i))
59-
);
78+
$this->components->info(sprintf('%d of %d %s retried.',
79+
$counter, $amount, Str::plural('failed job', $amount)
80+
));
6081

6182
return self::SUCCESS;
6283
}
6384

64-
private function retryFailedJobs(RedisJobRepository $repository): int
85+
private function resetFailedJobs(RedisJobRepository $repository): int
6586
{
66-
if (! $this->confirm('Really retry all failed jobs?')) {
67-
$this->components->info('Process terminated by user');
87+
if ($this->confirm('Reset all failed jobs and their counters?')) {
88+
$repository->recentFailedJobExpires = 0;
89+
$repository->trimRecentJobs();
6890

69-
return self::SUCCESS;
91+
$repository->failedJobExpires = 0;
92+
$repository->trimFailedJobs();
7093
}
7194

72-
$i = $repository->getFailed()->each(function ($job) {
73-
dispatch(new RetryFailedJob($job->id));
74-
})->count();
95+
return self::SUCCESS;
96+
}
7597

76-
$this->components->info(
77-
sprintf('%d %s retried.', $i, Str::plural(' job', $i))
78-
);
98+
private function getFailedJobs(RedisJobRepository $repository, int $amount): array
99+
{
100+
$failedJobs = $repository->getFailed($afterIndex = -1);
101+
$jobs = [];
102+
103+
while ($failedJobs->count() > 0) {
104+
foreach ($failedJobs as $failedJob) {
105+
$jobs[] = $failedJob->id;
106+
}
107+
$failedJobs = $repository->getFailed($afterIndex += 50);
108+
}
79109

80-
return self::SUCCESS;
110+
// sort all jobs in descending order
111+
$jobs = array_reverse($jobs);
112+
113+
return array_slice($jobs, 0, $amount);
81114
}
82115
}

0 commit comments

Comments
 (0)