Issues (219)

Command/PruneCommand.php (4 issues)

1
<?php
2
3
namespace Dtc\QueueBundle\Command;
4
5
use Dtc\QueueBundle\Exception\UnsupportedException;
6
use Dtc\QueueBundle\Manager\JobManagerInterface;
7
use Dtc\QueueBundle\Manager\JobTimingManager;
8
use Dtc\QueueBundle\Manager\RunManager;
9
use Dtc\QueueBundle\Util\Util;
10
use Symfony\Component\Console\Command\Command;
0 ignored issues
show
The type Symfony\Component\Console\Command\Command was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Symfony\Component\Console\Input\InputArgument;
0 ignored issues
show
The type Symfony\Component\Console\Input\InputArgument was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Input\InputOption;
0 ignored issues
show
The type Symfony\Component\Console\Input\InputOption was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Symfony\Component\Console\Output\OutputInterface;
15
16
class PruneCommand extends Command
17
{
18
    public 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';
19
20
    /** @var JobManagerInterface */
21
    private $jobManager;
22
23
    /** @var RunManager */
24
    private $runManager;
25
26
    /** @var JobTimingManager */
27
    private $jobTimingManager;
28
29 5
    protected function configure(): void
30
    {
31
        $this
32 5
        ->setName('dtc:queue:prune')
33 5
        ->setDescription('Prune jobs')
34 5
        ->addArgument('type', InputArgument::REQUIRED, '<stalled|stalled_runs|exception|expired|old|old_runs|old_job_timings> Prune stalled, exception, expired, or old jobs')
35 5
            ->addOption('older', null, InputOption::VALUE_REQUIRED, self::OLDER_MESSAGE);
36 5
    }
37
38 5
    public function setJobManager($jobManager)
39
    {
40 5
        $this->jobManager = $jobManager;
41 5
    }
42
43 5
    public function setRunManager($runManager)
44
    {
45 5
        $this->runManager = $runManager;
46 5
    }
47
48 5
    public function setJobTimingManager($jobTimingManager)
49
    {
50 5
        $this->jobTimingManager = $jobTimingManager;
51 5
    }
52
53 5
    protected function execute(InputInterface $input, OutputInterface $output): int
54
    {
55 5
        $type = $input->getArgument('type');
56 5
        switch ($type) {
57 5
            case 'erroneous':
58
                $output->writeln("(Warning): 'erroneous' is deprecated, please use 'exception' instead");
59
                $this->pruneExceptionJobs($output);
60
                break;
61 5
            case 'exception':
62 1
                $this->pruneExceptionJobs($output);
63 1
                break;
64 4
            case 'expired':
65 1
                $count = $this->jobManager->pruneExpiredJobs();
66 1
                $output->writeln("$count Expired Job(s) pruned");
67 1
                break;
68
            default:
69 3
                return $this->executeStalledOther($input, $output);
70
        }
71
72 2
        return $this::SUCCESS;
73
    }
74
75 1
    protected function pruneExceptionJobs(OutputInterface $output)
76
    {
77
        // @TODO: move this to dependency injection.
78 1
        $count = $this->jobManager->pruneExceptionJobs();
79 1
        $output->writeln("$count Job(s) with status 'exception' pruned");
80 1
    }
81
82 3
    public function executeStalledOther(InputInterface $input, OutputInterface $output)
83
    {
84 3
        $type = $input->getArgument('type');
85 3
        switch ($type) {
86 3
            case 'stalled':
87 1
                $count = $this->jobManager->pruneStalledJobs();
0 ignored issues
show
The method pruneStalledJobs() does not exist on Dtc\QueueBundle\Manager\JobManagerInterface. It seems like you code against a sub-type of Dtc\QueueBundle\Manager\JobManagerInterface such as Dtc\QueueBundle\Manager\StallableJobManager. ( Ignorable by Annotation )

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

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