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

RunCommand::configure()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 65
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 2.0069

Importance

Changes 0
Metric Value
dl 0
loc 65
ccs 44
cts 50
cp 0.88
rs 9.3571
c 0
b 0
f 0
cc 2
eloc 51
nc 2
nop 0
crap 2.0069

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Dtc\QueueBundle\Command;
4
5
use Dtc\QueueBundle\Exception\ClassNotSubclassException;
6
use Dtc\QueueBundle\Model\Job;
7
use Dtc\QueueBundle\Run\Loop;
8
use Dtc\QueueBundle\Util\Util;
9
use Psr\Log\LoggerInterface;
10
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
11
use Symfony\Component\Console\Input\InputArgument;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Input\InputOption;
14
use Symfony\Component\Console\Output\OutputInterface;
15
use Symfony\Component\HttpKernel\Kernel;
16
17
class RunCommand extends ContainerAwareCommand
18
{
19
    protected $loggerPrivate = false;
20
    protected $nanoSleepOption = null;
21
22 1
    protected function symfonyDetect()
23
    {
24 1
        $this->nanoSleepOption = null;
25 1
        if (class_exists('Symfony\Component\HttpKernel\Kernel')) {
26 1
            if (Kernel::VERSION_ID >= 30000) {
27 1
                $this->nanoSleepOption = 's';
28
            }
29 1
            if (Kernel::VERSION_ID >= 30400) {
30 1
                $this->loggerPrivate = true;
31
            }
32
        }
33 1
    }
34
35 1
    protected function configure()
36
    {
37 1
        $this->symfonyDetect();
38
        $options = array(
39 1
            new InputArgument('worker-name', InputArgument::OPTIONAL, 'Name of worker', null),
40 1
            new InputArgument('method', InputArgument::OPTIONAL, 'DI method of worker', null),
41 1
            new InputOption(
42 1
                'id',
43 1
                'i',
44 1
                InputOption::VALUE_REQUIRED,
45 1
                'Id of Job to run',
46 1
                null
47
            ),
48 1
            new InputOption(
49 1
                'max-count',
50 1
                'm',
51 1
                InputOption::VALUE_REQUIRED,
52 1
                'Maximum number of jobs to work on before exiting',
53 1
                null
54
            ),
55 1
            new InputOption(
56 1
                'duration',
57 1
                'd',
58 1
                InputOption::VALUE_REQUIRED,
59 1
                'Duration to run for in seconds',
60 1
                null
61
            ),
62 1
            new InputOption(
63 1
                'timeout',
64 1
                't',
65 1
                InputOption::VALUE_REQUIRED,
66 1
                'Process timeout in seconds (hard exit of process regardless)',
67 1
                3600
68
            ),
69 1
            new InputOption(
70 1
                'nano-sleep',
71 1
                $this->nanoSleepOption,
72 1
                InputOption::VALUE_REQUIRED,
73 1
                'If using duration, this is the time to sleep when there\'s no jobs in nanoseconds',
74 1
                500000000
75
            ),
76 1
            new InputOption(
77 1
                'disable-gc',
78 1
                null,
79 1
                InputOption::VALUE_NONE,
80 1
                'Disable garbage collection'
81
            ),
82
        );
83
84
        // Symfony 4 and Symfony 3.4 out-of-the-box makes the logger private
85 1
        if (!$this->loggerPrivate) {
86
            $options[] =
87
                new InputOption(
88
                    'logger',
89
                    'l',
90
                    InputOption::VALUE_REQUIRED,
91
                    'Log using the logger service specified, or output to console if null (or an invalid logger service id) is passed in'
92
                );
93
        }
94
95
        $this
96 1
            ->setName('dtc:queue:run')
97 1
            ->setDefinition($options)
98 1
            ->setDescription('Start up a job in queue');
99 1
    }
100
101 1
    protected function execute(InputInterface $input, OutputInterface $output)
102
    {
103 1
        $start = microtime(true);
104 1
        $container = $this->getContainer();
105 1
        $loop = $container->get('dtc_queue.run.loop');
106 1
        $loop->setOutput($output);
107 1
        $workerName = $input->getArgument('worker-name');
108 1
        $methodName = $input->getArgument('method');
109 1
        $maxCount = $input->getOption('max-count');
110 1
        $duration = $input->getOption('duration');
111 1
        $processTimeout = $input->getOption('timeout');
112 1
        $nanoSleep = $input->getOption('nano-sleep');
113 1
        $loggerService = !$this->loggerPrivate ? $input->getOption('logger', null) : null;
0 ignored issues
show
Unused Code introduced by
The call to InputInterface::getOption() has too many arguments starting with null.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
114 1
        $disableGc = $input->getOption('disable-gc', false);
0 ignored issues
show
Unused Code introduced by
The call to InputInterface::getOption() has too many arguments starting with false.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
115 1
        $this->setGc($disableGc);
116
117 1
        $this->setLoggerService($loop, $loggerService);
118
119 1
        $maxCount = Util::validateIntNull('max_count', $maxCount, 32);
120 1
        $duration = Util::validateIntNull('duration', $duration, 32);
121 1
        $nanoSleep = Util::validateIntNull('nano_sleep', $nanoSleep, 63);
122 1
        $processTimeout = Util::validateIntNull('timeout', $processTimeout, 32);
123 1
        $loop->checkMaxCountDuration($maxCount, $duration, $processTimeout);
124
125
        // Check to see if there are other instances
126 1
        set_time_limit($processTimeout); // Set timeout on the process
127
128 1
        if ($jobId = $input->getOption('id')) {
129
            return $loop->runJobById($start, $jobId); // Run a single job
130
        }
131
132 1
        return $loop->runLoop($start, $workerName, $methodName, $maxCount, $duration, $nanoSleep);
133
    }
134
135
    /**
136
     * @param bool $disableGc
137
     */
138 1
    protected function setGc($disableGc)
139
    {
140 1
        if ($disableGc) {
141
            if (gc_enabled()) {
142
                gc_disable();
143
            }
144
145
            return;
146
        }
147
148 1
        if (!gc_enabled()) {
149
            gc_enable();
150
        }
151 1
    }
152
153 1
    protected function setLoggerService(Loop $loop, $loggerService)
154
    {
155 1
        if (!$loggerService) {
156 1
            return;
157
        }
158
159
        $container = $this->getContainer();
160
        if (!$container->has($loggerService)) {
161
            return;
162
        }
163
164
        $logger = $container->get($loggerService);
165
        if (!$logger instanceof LoggerInterface) {
166
            throw new ClassNotSubclassException("$loggerService must be instance of Psr\\Log\\LoggerInterface");
167
        }
168
        $loop->setLogger($logger);
169
    }
170
}
171