Completed
Push — master ( 83ec40...868eb8 )
by Matthew
19:20
created

PruneCommand::pruneExceptionJobs()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

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