GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — feature/support_parallel_worke... ( 483e06...fceac2 )
by Aleh
01:38
created

AbstractWorker   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 87.72%

Importance

Changes 0
Metric Value
dl 0
loc 165
ccs 50
cts 57
cp 0.8772
rs 10
c 0
b 0
f 0
wmc 15
lcom 1
cbo 2

12 Methods

Rating   Name   Duplication   Size   Complexity  
getJobRunner() 0 1 ?
getScheduler() 0 1 ?
A hp ➔ pcntl_signal() 0 3 1
A hp ➔ pcntl_signal_dispatch() 0 3 1
A run() 0 19 2
A isRunning() 0 14 3
A shutdown() 0 4 1
A setMaxIterations() 0 7 2
A getSeconds() 0 6 1
A init() 0 14 3
A registerSigHandlers() 0 23 2
A getMaxIterations() 0 4 1
1
<?php
2
3
namespace Scheduler\Worker;
4
5
use DateInterval;
6
use DateTime;
7
use Scheduler\Exception\SchedulerException;
8
use Scheduler\JobRunner\JobRunnerInterface;
9
use Scheduler\SchedulerInterface;
10
11
/**
12
 * Class AbstractWorker
13
 * @package Scheduler\Worker
14
 * @author Aleh Hutnikau, <[email protected]>
15
 */
16
abstract class AbstractWorker implements WorkerInterface
17
{
18
    const DEFAULT_ITERATION_INTERVAL = 'PT60S';
19
20
    /** @var DateTime */
21
    private $from;
22
23
    /** @var DateInterval */
24
    private $interval;
25
26
    /** @var bool */
27
    private $shutdown = false;
28
29
    /** @var integer */
30
    private $iteration = 0;
31
32
    /** @var integer */
33
    private $maxIterations = 1000;
34
35
    /**
36
     * @param integer $startTime
37
     * @param string $interval
38
     * @return mixed|string
39
     * @throws SchedulerException
40
     */
41 2
    public function run($startTime, $interval)
42
    {
43 2
        $this->init($startTime, $interval);
44 1
        $jobRunner = $this->getJobRunner();
45
46 1
        $from = clone($this->from);
47 1
        $oneSecondInterval = new \DateInterval('PT1S');
48
49 1
        while ($this->isRunning()) {
50 1
            $to = DateTime::createFromFormat('U', time(), new \DateTimeZone('UTC'));
51 1
            $jobRunner->run($this->getScheduler(), $from, $to, true);
0 ignored issues
show
Security Bug introduced by
It seems like $from defined by clone $to on line 52 can also be of type false; however, Scheduler\JobRunner\JobRunnerInterface::run() does only seem to accept object<DateTimeInterface>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
Security Bug introduced by
It seems like $to defined by \DateTime::createFromFor...w \DateTimeZone('UTC')) on line 50 can also be of type false; however, Scheduler\JobRunner\JobRunnerInterface::run() does only seem to accept null|object<DateTimeInterface>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
52 1
            $from = clone($to);
53 1
            $from->add($oneSecondInterval);
54 1
            sleep($this->getSeconds($this->interval));
55 1
            $this->iteration++;
56
        }
57
58 1
        return 'Shut down scheduler worker';
59
    }
60
61
    /**
62
     * @return JobRunnerInterface
63
     */
64
    abstract protected function getJobRunner();
65
66
    /**
67
     * @return SchedulerInterface
68
     */
69
    abstract protected function getScheduler();
70
71
    /**
72
     * @return bool
73
     */
74 1
    public function isRunning()
75
    {
76 1
        pcntl_signal_dispatch();
77
78 1
        if ($this->iteration >= $this->getMaxIterations()) {
79 1
            $this->shutdown();
80
        }
81
82 1
        if ($this->shutdown) {
83 1
            return false;
84
        }
85
86 1
        return true;
87
    }
88
89
    /**
90
     * Set marker to shutdown after finishing current iteration
91
     */
92 1
    public function shutdown()
93
    {
94 1
        $this->shutdown = true;
95 1
    }
96
97
    /**
98
     * @param $iterations
99
     * @throws SchedulerException
100
     * @return mixed|void
101
     */
102 2
    public function setMaxIterations($iterations)
103
    {
104 2
        if (!is_integer($iterations)) {
105 1
            throw new SchedulerException('$iterations parameter must be integer');
106
        }
107 1
        $this->maxIterations = $iterations;
108 1
    }
109
110
    /**
111
     * Get amount of seconds in date interval
112
     *
113
     * @param DateInterval $interval
114
     * @return int
115
     * @throws \Exception
116
     */
117 1
    private function getSeconds(DateInterval $interval)
118
    {
119 1
        $date = new \DateTimeImmutable('now', new \DateTimeZone('UTC'));
120 1
        $date2 = $date->add($interval);
121 1
        return $date2->getTimestamp() - $date->getTimestamp();
122
    }
123
124
    /**
125
     * @param integer $startTime
126
     * @param string $interval
127
     * @throws
128
     */
129 2
    private function init($startTime, $interval)
130
    {
131 2
        if (!is_numeric($startTime)) {
132 1
            throw new SchedulerException('Start time parameter must be numeric');
133
        }
134 1
        $this->from = new DateTime('@' . $startTime, new \DateTimeZone('UTC'));
135
136 1
        $this->interval = new \DateInterval(self::DEFAULT_ITERATION_INTERVAL);
137 1
        if ($interval !== null) {
138 1
            $this->interval = new \DateInterval($interval);
139
        }
140
141 1
        $this->registerSigHandlers();
142 1
    }
143
144
    /**
145
     * Register signal handlers that a worker should respond to.
146
     *
147
     * TERM/INT/QUIT: Shutdown after the current job is finished then exit.
148
     */
149 1
    private function registerSigHandlers()
150
    {
151 1
        if (!function_exists('pcntl_signal')) {
152
            //worker ran without pcntl
153
            function pcntl_signal() {
154
                //do nothing
155
            }
156
            define('SIGTERM', 15);
157
            define('SIGINT', 2);
158
            define('SIGQUIT', 3);
159
        }
160 1
        if (!function_exists('pcntl_signal_dispatch')) {
161
            function pcntl_signal_dispatch() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
162
                //do nothing
163
            };
164
        }
165
166
        declare(ticks = 1);
167
168 1
        pcntl_signal(SIGTERM, [$this, 'shutdown']);
169 1
        pcntl_signal(SIGINT, [$this, 'shutdown']);
170 1
        pcntl_signal(SIGQUIT, [$this, 'shutdown']);
171 1
    }
172
173
    /**
174
     * @return integer
175
     */
176 1
    public function getMaxIterations()
177
    {
178 1
        return $this->maxIterations;
179
    }
180
}