Passed
Pull Request — master (#61)
by Peter
09:08
created

PruneCommand::pruneOlderThan()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 4.0023

Importance

Changes 0
Metric Value
cc 4
eloc 19
nc 4
nop 3
dl 0
loc 23
ccs 18
cts 19
cp 0.9474
crap 4.0023
rs 8.7972
c 0
b 0
f 0
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
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 job with error status')
22 5
        ->addArgument('type', InputArgument::REQUIRED, '<stalled|stalled_runs|error|expired|old|old_runs|old_job_timings> Prune stalled, erroneous, 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
        $container = $this->getContainer();
29 5
        $jobManager = $container->get('dtc_queue.manager.job');
30 5
        $type = $input->getArgument('type');
31 5
        switch ($type) {
32 5
            case 'error':
33 1
                $count = $jobManager->pruneErroneousJobs();
34 1
                $output->writeln("$count Erroneous Job(s) pruned");
35 1
                break;
36 4
            case 'expired':
37 1
                $count = $jobManager->pruneExpiredJobs();
38 1
                $output->writeln("$count Expired Job(s) pruned");
39 1
                break;
40
            default:
41 3
                return $this->executeStalledOther($input, $output);
42
        }
43
44 2
        return 0;
45
    }
46
47 3
    public function executeStalledOther(InputInterface $input, OutputInterface $output)
48
    {
49 3
        $container = $this->getContainer();
50 3
        $jobManager = $container->get('dtc_queue.manager.job');
51 3
        $type = $input->getArgument('type');
52 3
        switch ($type) {
53 3
            case 'stalled':
54 1
                $count = $jobManager->pruneStalledJobs();
55 1
                $output->writeln("$count Stalled Job(s) pruned");
56 1
                break;
57 2
            case 'stalled_runs':
58 1
                $count = $container->get('dtc_queue.manager.run')->pruneStalledRuns();
59 1
                $output->writeln("$count Stalled Job(s) pruned");
60 1
                break;
61
            default:
62 1
                return $this->executeOlder($input, $output);
63
        }
64
65 2
        return 0;
66
    }
67
68 1
    public function executeOlder(InputInterface $input, OutputInterface $output)
69
    {
70 1
        $older = $input->getOption('older');
71 1
        $type = $input->getArgument('type');
72 1
        if (!$older) {
73 1
            $output->writeln('<error>--older must be specified</error>');
74
75 1
            return 1;
76
        }
77 1
        if (!preg_match("/(\d+)([d|m|y|h|i|s]){0,1}$/", $older, $matches)) {
78 1
            $output->writeln('<error>Wrong format for --older</error>');
79
80 1
            return 1;
81
        }
82
83 1
        return $this->pruneOldJobs($matches, $type, $output);
84
    }
85
86
    /**
87
     * @param string[]        $matches
88
     * @param string          $type
89
     * @param OutputInterface $output
90
     *
91
     * @return int
92
     *
93
     * @throws \Exception
94
     */
95 1
    protected function pruneOldJobs(array $matches, $type, OutputInterface $output)
96
    {
97 1
        $durationOrTimestamp = intval($matches[1]);
98 1
        $modifier = isset($matches[2]) ? $matches[2] : null;
99
100 1
        if (!$durationOrTimestamp) {
101
            $output->writeln('<error>No duration or timestamp passed in.</error>');
102
103
            return 1;
104
        }
105 1
        $olderThan = Util::getMicrotimeDateTime();
106 1
        if (null === $modifier) {
107 1
            $olderThan->setTimestamp($durationOrTimestamp);
108
        } else {
109 1
            $interval = $this->getInterval($modifier, $durationOrTimestamp);
110 1
            $olderThan->sub($interval);
111
        }
112
113 1
        return $this->pruneOlderThan($type, $olderThan, $output);
114
    }
115
116
    /**
117
     * @param string          $type
118
     * @param \DateTime       $olderThan
119
     * @param OutputInterface $output
120
     *
121
     * @return int
122
     *
123
     * @throws UnsupportedException
124
     */
125 1
    protected function pruneOlderThan($type, \DateTime $olderThan, OutputInterface $output)
126
    {
127 1
        $container = $this->getContainer();
128 1
        $typeName = null;
129 1
        switch ($type) {
130 1
            case 'old':
131 1
                $count = $container->get('dtc_queue.manager.job')->pruneArchivedJobs($olderThan);
132 1
                $typeName = 'Job';
133 1
                break;
134 1
            case 'old_runs':
135 1
                $count = $container->get('dtc_queue.manager.run')->pruneArchivedRuns($olderThan);
136 1
                $typeName = 'Run';
137 1
                break;
138 1
            case 'old_job_timings':
139 1
                $count = $container->get('dtc_queue.manager.run')->pruneJobTimings($olderThan);
140 1
                $typeName = 'Job Timing';
141 1
                break;
142
            default:
143
                throw new UnsupportedException("Unknown type $type");
144
        }
145 1
        $output->writeln("$count Archived $typeName(s) pruned");
146
147 1
        return 0;
148
    }
149
150
    /**
151
     * Returns the date interval based on the modifier and the duration.
152
     *
153
     * @param string $modifier
154
     * @param int    $duration
155
     *
156
     * @return \DateInterval
157
     *
158
     * @throws UnsupportedException
159
     */
160 1
    protected function getInterval($modifier, $duration)
161
    {
162 1
        switch ($modifier) {
163 1
            case 'd':
164 1
                $interval = new \DateInterval("P${duration}D");
165 1
                break;
166 1
            case 'm':
167 1
                $interval = new \DateInterval("P${duration}M");
168
                break;
169
            case 'y':
170
                $interval = new \DateInterval("P${duration}Y");
171 1
                break;
172
            default:
173 1
                $interval = $this->getIntervalTime($modifier, $duration);
174
        }
175
176 1
        return $interval;
177
    }
178
179
    /**
180
     * @param string $modifier
181
     * @param int    $duration
182
     *
183
     * @return \DateInterval
184
     *
185
     * @throws UnsupportedException
186
     */
187
    protected function getIntervalTime($modifier, $duration)
188
    {
189 1
        switch ($modifier) {
190 1
            case 'h':
191 1
                $interval = new \DateInterval("PT${duration}H");
192 1
                break;
193 1
            case 'i':
194 1
                $seconds = $duration * 60;
195 1
                $interval = new \DateInterval("PT${seconds}S");
196 1
                break;
197 1
            case 's':
198 1
                $interval = new \DateInterval("PT${duration}S");
199 1
                break;
200
            default:
201
                throw new UnsupportedException("Unknown duration modifier: $modifier");
202
        }
203
204 1
        return $interval;
205
    }
206
}
207