Passed
Push — master ( 4d8734...991786 )
by Matthew
09:35 queued 06:44
created

PruneCommand   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 203
Duplicated Lines 0 %

Test Coverage

Coverage 93.27%

Importance

Changes 0
Metric Value
eloc 111
dl 0
loc 203
ccs 97
cts 104
cp 0.9327
rs 10
c 0
b 0
f 0
wmc 28

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getIntervalTime() 0 18 4
A pruneOlderThan() 0 23 4
A configure() 0 7 1
A pruneOldJobs() 0 19 4
A getInterval() 0 17 4
A pruneExceptionJobs() 0 6 1
A execute() 0 22 4
A executeStalledOther() 0 19 3
A executeOlder() 0 16 3
1
<?php
2
3
namespace Dtc\QueueBundle\Command;
4
5
use Dtc\QueueBundle\Exception\UnsupportedException;
6
use Dtc\QueueBundle\Util\Util;
7
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
8
use Symfony\Component\Console\Input\InputArgument;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Input\InputOption;
11
use Symfony\Component\Console\Output\OutputInterface;
12
13
class PruneCommand extends ContainerAwareCommand
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Bundle\Framework...d\ContainerAwareCommand has been deprecated: since Symfony 4.2, use {@see Command} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

13
class PruneCommand extends /** @scrutinizer ignore-deprecated */ ContainerAwareCommand
Loading history...
14
{
15
    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';
16
17 5
    protected function configure()
18
    {
19
        $this
20 5
        ->setName('dtc:queue:prune')
21 5
        ->setDescription('Prune jobs')
22 5
        ->addArgument('type', InputArgument::REQUIRED, '<stalled|stalled_runs|exception|expired|old|old_runs|old_job_timings> Prune stalled, exception, expired, or old jobs')
23 5
            ->addOption('older', null, InputOption::VALUE_REQUIRED, self::OLDER_MESSAGE);
24 5
    }
25
26 5
    protected function execute(InputInterface $input, OutputInterface $output)
27
    {
28 5
        $type = $input->getArgument('type');
29
        switch ($type) {
30 5
            case 'erroneous':
31
                $output->writeln("(Warning): 'erroneous' is deprecated, please use 'exception' instead");
32
                $this->pruneExceptionJobs($output);
33
                break;
34 5
            case 'exception':
35 1
                $this->pruneExceptionJobs($output);
36 1
                break;
37 4
            case 'expired':
38 1
                $container = $this->getContainer();
39 1
                $jobManager = $container->get('dtc_queue.manager.job');
40 1
                $count = $jobManager->pruneExpiredJobs();
41 1
                $output->writeln("$count Expired Job(s) pruned");
42 1
                break;
43
            default:
44 3
                return $this->executeStalledOther($input, $output);
45
        }
46
47 2
        return 0;
48
    }
49
50 1
    protected function pruneExceptionJobs(OutputInterface $output)
51
    {
52 1
        $container = $this->getContainer();
53 1
        $jobManager = $container->get('dtc_queue.manager.job');
54 1
        $count = $jobManager->pruneExceptionJobs();
55 1
        $output->writeln("$count Job(s) with status 'exception' pruned");
56 1
    }
57
58 3
    public function executeStalledOther(InputInterface $input, OutputInterface $output)
59
    {
60 3
        $container = $this->getContainer();
61 3
        $jobManager = $container->get('dtc_queue.manager.job');
62 3
        $type = $input->getArgument('type');
63
        switch ($type) {
64 3
            case 'stalled':
65 1
                $count = $jobManager->pruneStalledJobs();
66 1
                $output->writeln("$count Stalled Job(s) pruned");
67 1
                break;
68 2
            case 'stalled_runs':
69 1
                $count = $container->get('dtc_queue.manager.run')->pruneStalledRuns();
70 1
                $output->writeln("$count Stalled Job(s) pruned");
71 1
                break;
72
            default:
73 1
                return $this->executeOlder($input, $output);
74
        }
75
76 2
        return 0;
77
    }
78
79 1
    public function executeOlder(InputInterface $input, OutputInterface $output)
80
    {
81 1
        $older = $input->getOption('older');
82 1
        $type = $input->getArgument('type');
83 1
        if (!$older) {
84 1
            $output->writeln('<error>--older must be specified</error>');
85
86 1
            return 1;
87
        }
88 1
        if (!preg_match("/(\d+)([d|m|y|h|i|s]){0,1}$/", $older, $matches)) {
89 1
            $output->writeln('<error>Wrong format for --older</error>');
90
91 1
            return 1;
92
        }
93
94 1
        return $this->pruneOldJobs($matches, $type, $output);
0 ignored issues
show
Bug introduced by
It seems like $type can also be of type string[]; however, parameter $type of Dtc\QueueBundle\Command\...Command::pruneOldJobs() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

94
        return $this->pruneOldJobs($matches, /** @scrutinizer ignore-type */ $type, $output);
Loading history...
95
    }
96
97
    /**
98
     * @param string[]        $matches
99
     * @param string          $type
100
     * @param OutputInterface $output
101
     *
102
     * @return int
103
     *
104
     * @throws \Exception
105
     */
106 1
    protected function pruneOldJobs(array $matches, $type, OutputInterface $output)
107
    {
108 1
        $durationOrTimestamp = intval($matches[1]);
109 1
        $modifier = isset($matches[2]) ? $matches[2] : null;
110
111 1
        if (!$durationOrTimestamp) {
112
            $output->writeln('<error>No duration or timestamp passed in.</error>');
113
114
            return 1;
115
        }
116 1
        $olderThan = Util::getMicrotimeDateTime();
117 1
        if (null === $modifier) {
118 1
            $olderThan->setTimestamp($durationOrTimestamp);
119
        } else {
120 1
            $interval = $this->getInterval($modifier, $durationOrTimestamp);
121 1
            $olderThan->sub($interval);
122
        }
123
124 1
        return $this->pruneOlderThan($type, $olderThan, $output);
125
    }
126
127
    /**
128
     * @param string          $type
129
     * @param \DateTime       $olderThan
130
     * @param OutputInterface $output
131
     *
132
     * @return int
133
     *
134
     * @throws UnsupportedException
135
     */
136 1
    protected function pruneOlderThan($type, \DateTime $olderThan, OutputInterface $output)
137
    {
138 1
        $container = $this->getContainer();
139 1
        $typeName = null;
140
        switch ($type) {
141 1
            case 'old':
142 1
                $count = $container->get('dtc_queue.manager.job')->pruneArchivedJobs($olderThan);
143 1
                $typeName = 'Job';
144 1
                break;
145 1
            case 'old_runs':
146 1
                $count = $container->get('dtc_queue.manager.run')->pruneArchivedRuns($olderThan);
147 1
                $typeName = 'Run';
148 1
                break;
149 1
            case 'old_job_timings':
150 1
                $count = $container->get('dtc_queue.manager.job_timing')->pruneJobTimings($olderThan);
151 1
                $typeName = 'Job Timing';
152 1
                break;
153
            default:
154
                throw new UnsupportedException("Unknown type $type");
155
        }
156 1
        $output->writeln("$count Archived $typeName(s) pruned");
157
158 1
        return 0;
159
    }
160
161
    /**
162
     * Returns the date interval based on the modifier and the duration.
163
     *
164
     * @param string $modifier
165
     * @param int    $duration
166
     *
167
     * @return \DateInterval
168
     *
169
     * @throws UnsupportedException
170
     */
171 1
    protected function getInterval($modifier, $duration)
172
    {
173
        switch ($modifier) {
174 1
            case 'd':
175 1
                $interval = new \DateInterval("P${duration}D");
176 1
                break;
177 1
            case 'm':
178 1
                $interval = new \DateInterval("P${duration}M");
179
                break;
180
            case 'y':
181
                $interval = new \DateInterval("P${duration}Y");
182 1
                break;
183
            default:
184 1
                $interval = $this->getIntervalTime($modifier, $duration);
185
        }
186
187 1
        return $interval;
188
    }
189
190
    /**
191
     * @param string $modifier
192
     * @param int    $duration
193
     *
194
     * @return \DateInterval
195
     *
196
     * @throws UnsupportedException
197
     */
198
    protected function getIntervalTime($modifier, $duration)
199
    {
200
        switch ($modifier) {
201 1
            case 'h':
202 1
                $interval = new \DateInterval("PT${duration}H");
203 1
                break;
204 1
            case 'i':
205 1
                $seconds = $duration * 60;
206 1
                $interval = new \DateInterval("PT${seconds}S");
207 1
                break;
208 1
            case 's':
209 1
                $interval = new \DateInterval("PT${duration}S");
210 1
                break;
211
            default:
212
                throw new UnsupportedException("Unknown duration modifier: $modifier");
213
        }
214
215 1
        return $interval;
216
    }
217
}
218