Completed
Push — master ( 4109b7...859c70 )
by Matthew
08:07 queued 02:26
created

PruneCommand::pruneOldJobs()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4.0582

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 11
cts 13
cp 0.8462
rs 9.2
c 0
b 0
f 0
cc 4
eloc 13
nc 6
nop 3
crap 4.0582
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)
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...
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)
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...
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;
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...
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