Completed
Push — master ( d448ac...513048 )
by Matthew
31:40 queued 17:02
created

PruneCommand::pruneOldJobs()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4.074

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 10
cts 12
cp 0.8333
rs 9.2
c 0
b 0
f 0
cc 4
eloc 13
nc 6
nop 3
crap 4.074
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 View Code Duplication
    protected function execute(InputInterface $input, OutputInterface $output)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
27
    {
28 5
        $container = $this->getContainer();
29 5
        $jobManager = $container->get('dtc_queue.manager.job');
30 5
        $type = $input->getArgument('type');
31
        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 View Code Duplication
    public function executeStalledOther(InputInterface $input, OutputInterface $output)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
48
    {
49 3
        $container = $this->getContainer();
50 3
        $jobManager = $container->get('dtc_queue.manager.job');
51 3
        $type = $input->getArgument('type');
52
        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;
0 ignored issues
show
Unused Code introduced by
$typeName is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
129
        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
        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
        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