@@ -16,67 +16,100 @@ class FailedJobs extends Command implements Isolatable, PromptsForMissingInput
16
16
/**
17
17
* @var string
18
18
*/
19
- protected $ signature = 'codebarista:failed-jobs ' ;
19
+ protected $ signature = 'codebarista:failed-jobs {action} ' ;
20
20
21
21
/**
22
22
* @var string
23
23
*/
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
+ }
25
32
26
33
public function handle (RedisJobRepository $ repository ): int
27
34
{
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 ),
36
41
default => self ::INVALID ,
37
42
};
43
+
38
44
}
39
45
40
- private function deleteFailedJobs (RedisJobRepository $ repository ): int
46
+ private function deleteFailedJobs (RedisJobRepository $ repository, int $ amount ): int
41
47
{
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 ;
44
51
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
+ ));
46
61
}
47
62
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 );
49
69
50
- // What a hack...but it works
51
- $ repository ->recentFailedJobExpires = 0 ;
52
- $ repository ->trimRecentJobs ();
70
+ $ failedJobs = $ this ->getFailedJobs ($ repository , $ chunk );
71
+ $ counter = 0 ;
53
72
54
- $ repository ->failedJobExpires = 0 ;
55
- $ repository ->trimFailedJobs ();
73
+ foreach ($ failedJobs as $ jobId ) {
74
+ dispatch (new RetryFailedJob ($ jobId ));
75
+ $ counter += $ repository ->deleteFailed ($ jobId );
76
+ }
56
77
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
+ )) ;
60
81
61
82
return self ::SUCCESS ;
62
83
}
63
84
64
- private function retryFailedJobs (RedisJobRepository $ repository ): int
85
+ private function resetFailedJobs (RedisJobRepository $ repository ): int
65
86
{
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 ();
68
90
69
- return self ::SUCCESS ;
91
+ $ repository ->failedJobExpires = 0 ;
92
+ $ repository ->trimFailedJobs ();
70
93
}
71
94
72
- $ i = $ repository ->getFailed ()->each (function ($ job ) {
73
- dispatch (new RetryFailedJob ($ job ->id ));
74
- })->count ();
95
+ return self ::SUCCESS ;
96
+ }
75
97
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
+ }
79
109
80
- return self ::SUCCESS ;
110
+ // sort all jobs in descending order
111
+ $ jobs = array_reverse ($ jobs );
112
+
113
+ return array_slice ($ jobs , 0 , $ amount );
81
114
}
82
115
}
0 commit comments