1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Dtc\QueueBundle\Command; |
4
|
|
|
|
5
|
|
|
use Dtc\QueueBundle\Exception\UnsupportedException; |
6
|
|
|
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; |
7
|
|
|
use Symfony\Component\Console\Input\InputArgument; |
8
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
9
|
|
|
use Symfony\Component\Console\Input\InputOption; |
10
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
11
|
|
|
|
12
|
|
|
class PruneCommand extends ContainerAwareCommand |
13
|
|
|
{ |
14
|
|
|
const OLDER_MESSAGE = '<int>[d|m|y|h|i|s] Specify how old the jobs should (defaults to timestamp unless a quantifier is specified [d_ays, m_onths, y_years, h_ours, i_minutes, s_econds'; |
15
|
|
|
|
16
|
5 |
|
protected function configure() |
17
|
|
|
{ |
18
|
5 |
|
$this |
19
|
5 |
|
->setName('dtc:queue:prune') |
20
|
5 |
|
->setDescription('Prune job with error status') |
21
|
5 |
|
->addArgument('type', InputArgument::REQUIRED, '<stalled|stalled_runs|error|expired|old|old_runs|old_job_timings> Prune stalled, erroneous, expired, or old jobs') |
22
|
5 |
|
->addOption('older', null, InputOption::VALUE_REQUIRED, self::OLDER_MESSAGE); |
23
|
5 |
|
} |
24
|
|
|
|
25
|
5 |
View Code Duplication |
protected function execute(InputInterface $input, OutputInterface $output) |
|
|
|
|
26
|
|
|
{ |
27
|
5 |
|
$container = $this->getContainer(); |
28
|
5 |
|
$jobManager = $container->get('dtc_queue.job_manager'); |
29
|
5 |
|
$type = $input->getArgument('type'); |
30
|
|
|
switch ($type) { |
31
|
5 |
|
case 'error': |
32
|
1 |
|
$count = $jobManager->pruneErroneousJobs(); |
33
|
1 |
|
$output->writeln("$count Erroneous Job(s) pruned"); |
34
|
1 |
|
break; |
35
|
4 |
|
case 'expired': |
36
|
1 |
|
$count = $jobManager->pruneExpiredJobs(); |
37
|
1 |
|
$output->writeln("$count Expired Job(s) pruned"); |
38
|
1 |
|
break; |
39
|
3 |
|
default: |
40
|
3 |
|
return $this->executeStalledOther($input, $output); |
41
|
3 |
|
} |
42
|
|
|
|
43
|
2 |
|
return 0; |
44
|
|
|
} |
45
|
|
|
|
46
|
3 |
View Code Duplication |
public function executeStalledOther(InputInterface $input, OutputInterface $output) |
|
|
|
|
47
|
|
|
{ |
48
|
3 |
|
$container = $this->getContainer(); |
49
|
3 |
|
$jobManager = $container->get('dtc_queue.job_manager'); |
50
|
3 |
|
$type = $input->getArgument('type'); |
51
|
|
|
switch ($type) { |
52
|
3 |
|
case 'stalled': |
53
|
1 |
|
$count = $jobManager->pruneStalledJobs(); |
54
|
1 |
|
$output->writeln("$count Stalled Job(s) pruned"); |
55
|
1 |
|
break; |
56
|
2 |
|
case 'stalled_runs': |
57
|
1 |
|
$count = $container->get('dtc_queue.run_manager')->pruneStalledRuns(); |
58
|
1 |
|
$output->writeln("$count Stalled Job(s) pruned"); |
59
|
1 |
|
break; |
60
|
1 |
|
default: |
61
|
1 |
|
return $this->executeOlder($input, $output); |
62
|
1 |
|
} |
63
|
|
|
|
64
|
2 |
|
return 0; |
65
|
|
|
} |
66
|
|
|
|
67
|
1 |
|
public function executeOlder(InputInterface $input, OutputInterface $output) |
68
|
|
|
{ |
69
|
1 |
|
$older = $input->getOption('older'); |
70
|
1 |
|
$type = $input->getArgument('type'); |
71
|
1 |
|
if (!$older) { |
72
|
1 |
|
$output->writeln('<error>--older must be specified</error>'); |
73
|
|
|
|
74
|
1 |
|
return 1; |
75
|
|
|
} |
76
|
1 |
|
if (!preg_match("/(\d+)([d|m|y|h|i|s]){0,1}$/", $older, $matches)) { |
77
|
1 |
|
$output->writeln('<error>Wrong format for --older</error>'); |
78
|
|
|
|
79
|
1 |
|
return 1; |
80
|
|
|
} |
81
|
|
|
|
82
|
1 |
|
return $this->pruneOldJobs($matches, $type, $output); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* @param string[] $matches |
87
|
|
|
* @param string $type |
88
|
|
|
* @param OutputInterface $output |
89
|
|
|
* |
90
|
|
|
* @return int |
91
|
|
|
* |
92
|
|
|
* @throws \Exception |
93
|
|
|
*/ |
94
|
1 |
|
protected function pruneOldJobs(array $matches, $type, OutputInterface $output) |
95
|
|
|
{ |
96
|
1 |
|
$durationOrTimestamp = intval($matches[1]); |
97
|
1 |
|
$modifier = isset($matches[2]) ? $matches[2] : null; |
98
|
|
|
|
99
|
1 |
|
if (!$durationOrTimestamp) { |
100
|
|
|
$output->writeln('<error>No duration or timestamp passed in.</error>'); |
101
|
|
|
|
102
|
|
|
return 1; |
103
|
|
|
} |
104
|
1 |
|
$olderThan = new \DateTime(); |
105
|
1 |
|
if (null === $modifier) { |
106
|
1 |
|
$olderThan->setTimestamp($durationOrTimestamp); |
107
|
1 |
|
} else { |
108
|
1 |
|
$interval = $this->getInterval($modifier, $durationOrTimestamp); |
109
|
1 |
|
$olderThan->sub($interval); |
110
|
|
|
} |
111
|
|
|
|
112
|
1 |
|
return $this->pruneOlderThan($type, $olderThan, $output); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* @param string $type |
117
|
|
|
* @param \DateTime $olderThan |
118
|
|
|
* @param OutputInterface $output |
119
|
|
|
* |
120
|
|
|
* @return int |
121
|
|
|
* |
122
|
|
|
* @throws UnsupportedException |
123
|
|
|
*/ |
124
|
1 |
|
protected function pruneOlderThan($type, \DateTime $olderThan, OutputInterface $output) |
125
|
|
|
{ |
126
|
1 |
|
$container = $this->getContainer(); |
127
|
1 |
|
$typeName = null; |
|
|
|
|
128
|
|
|
switch ($type) { |
129
|
1 |
|
case 'old': |
130
|
1 |
|
$count = $container->get('dtc_queue.job_manager')->pruneArchivedJobs($olderThan); |
131
|
1 |
|
$typeName = 'Job'; |
132
|
1 |
|
break; |
133
|
1 |
|
case 'old_runs': |
134
|
1 |
|
$count = $container->get('dtc_queue.run_manager')->pruneArchivedRuns($olderThan); |
135
|
1 |
|
$typeName = 'Run'; |
136
|
1 |
|
break; |
137
|
1 |
|
case 'old_job_timings': |
138
|
1 |
|
$count = $container->get('dtc_queue.run_manager')->pruneJobTimings($olderThan); |
139
|
1 |
|
$typeName = 'Job Timing'; |
140
|
1 |
|
break; |
141
|
|
|
default: |
142
|
|
|
throw new UnsupportedException("Unknown type $type"); |
143
|
|
|
} |
144
|
1 |
|
$output->writeln("$count Archived $typeName(s) pruned"); |
145
|
|
|
|
146
|
1 |
|
return 0; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Returns the date interval based on the modifier and the duration. |
151
|
|
|
* |
152
|
|
|
* @param string $modifier |
153
|
|
|
* @param int $duration |
154
|
|
|
* |
155
|
|
|
* @return \DateInterval |
156
|
|
|
* |
157
|
|
|
* @throws UnsupportedException |
158
|
|
|
*/ |
159
|
1 |
|
protected function getInterval($modifier, $duration) |
160
|
|
|
{ |
161
|
|
|
switch ($modifier) { |
162
|
1 |
|
case 'd': |
163
|
1 |
|
$interval = new \DateInterval("P${duration}D"); |
164
|
1 |
|
break; |
165
|
1 |
|
case 'm': |
166
|
1 |
|
$interval = new \DateInterval("P${duration}M"); |
167
|
|
|
break; |
168
|
|
|
case 'y': |
169
|
|
|
$interval = new \DateInterval("P${duration}Y"); |
170
|
1 |
|
break; |
171
|
1 |
|
default: |
172
|
1 |
|
$interval = $this->getIntervalTime($modifier, $duration); |
173
|
1 |
|
} |
174
|
|
|
|
175
|
1 |
|
return $interval; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* @param string $modifier |
180
|
|
|
* @param int $duration |
181
|
|
|
* |
182
|
|
|
* @return \DateInterval |
183
|
|
|
* |
184
|
|
|
* @throws UnsupportedException |
185
|
|
|
*/ |
186
|
|
|
protected function getIntervalTime($modifier, $duration) |
187
|
|
|
{ |
188
|
|
|
switch ($modifier) { |
189
|
1 |
|
case 'h': |
190
|
1 |
|
$interval = new \DateInterval("PT${duration}H"); |
191
|
1 |
|
break; |
192
|
1 |
|
case 'i': |
193
|
1 |
|
$seconds = $duration * 60; |
194
|
1 |
|
$interval = new \DateInterval("PT${seconds}S"); |
195
|
1 |
|
break; |
196
|
1 |
|
case 's': |
197
|
1 |
|
$interval = new \DateInterval("PT${duration}S"); |
198
|
1 |
|
break; |
199
|
|
|
default: |
200
|
|
|
throw new UnsupportedException("Unknown duration modifier: $modifier"); |
201
|
|
|
} |
202
|
|
|
|
203
|
1 |
|
return $interval; |
204
|
|
|
} |
205
|
|
|
} |
206
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.