Passed
Push — master ( ea1bad...3d3a35 )
by Matthew
08:46
created

StalledTrait::findRunningJobs()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 13
nc 6
nop 2
dl 0
loc 22
ccs 14
cts 14
cp 1
crap 5
rs 8.6737
c 0
b 0
f 0
1
<?php
2
3
namespace Dtc\QueueBundle\Doctrine;
4
5
use Dtc\QueueBundle\Model\BaseJob;
6
use Dtc\QueueBundle\Model\StallableJob;
7
use Dtc\QueueBundle\Util\Util;
8
9
trait StalledTrait
10
{
11
    /**
12
     * @param int   $if
13
     * @param int   $count
14
     * @param int   $saveCount
15
     * @param array $stalledJobs
16
     *
17
     * @return int
18
     */
19 2
    protected function runStalledLoop($i, $count, $saveCount, array $stalledJobs)
20
    {
21 2
        $resetCount = 0;
22 2
        for ($j = $i, $max = $i + $saveCount; $j < $max && $j < $count; ++$j) {
23
            /* StallableJob $job */
24 2
            $job = $stalledJobs[$j];
25 2
            $job->setStatus(StallableJob::STATUS_STALLED);
26 2
            if ($this->saveHistory($job)) {
0 ignored issues
show
Bug introduced by
It seems like saveHistory() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

26
            if ($this->/** @scrutinizer ignore-call */ saveHistory($job)) {
Loading history...
27 2
                ++$resetCount;
28
            }
29
        }
30
31 2
        return $resetCount;
32
    }
33
34
    /**
35
     * @param array $criterion
36
     * @param int   $limit
37
     * @param int   $offset
38
     */
39 2
    private function resetJobsByCriterion(
40
        array $criterion,
41
        $limit,
42
        $offset
43
    ) {
44 2
        $objectManager = $this->getObjectManager();
0 ignored issues
show
Bug introduced by
It seems like getObjectManager() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

44
        /** @scrutinizer ignore-call */ 
45
        $objectManager = $this->getObjectManager();
Loading history...
45 2
        $objectName = $this->getJobClass();
0 ignored issues
show
Bug introduced by
It seems like getJobClass() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

45
        /** @scrutinizer ignore-call */ 
46
        $objectName = $this->getJobClass();
Loading history...
46 2
        $archiveObjectName = $this->getJobArchiveClass();
0 ignored issues
show
Bug introduced by
It seems like getJobArchiveClass() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

46
        /** @scrutinizer ignore-call */ 
47
        $archiveObjectName = $this->getJobArchiveClass();
Loading history...
47 2
        $jobRepository = $objectManager->getRepository($objectName);
48 2
        $jobArchiveRepository = $objectManager->getRepository($archiveObjectName);
49 2
        $className = $jobRepository->getClassName();
50 2
        $metadata = $objectManager->getClassMetadata($className);
51 2
        $this->stopIdGenerator($objectName);
0 ignored issues
show
Bug introduced by
It seems like stopIdGenerator() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

51
        $this->/** @scrutinizer ignore-call */ 
52
               stopIdGenerator($objectName);
Loading history...
52 2
        $identifierData = $metadata->getIdentifier();
53 2
        $idColumn = isset($identifierData[0]) ? $identifierData[0] : 'id';
54 2
        $results = $jobArchiveRepository->findBy($criterion, [$idColumn => 'ASC'], $limit, $offset);
55 2
        $countProcessed = 0;
56
57 2
        foreach ($results as $jobArchive) {
58 2
            $countProcessed += $this->resetArchiveJob($jobArchive);
59
        }
60 2
        $objectManager->flush();
61
62 2
        $this->restoreIdGenerator($objectName);
0 ignored issues
show
Bug introduced by
It seems like restoreIdGenerator() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

62
        $this->/** @scrutinizer ignore-call */ 
63
               restoreIdGenerator($objectName);
Loading history...
63
64 2
        return $countProcessed;
65
    }
66
67 4
    protected function getStalledJobs($workerName = null, $method = null)
68
    {
69 4
        $count = $this->countJobsByStatus($this->getJobClass(), BaseJob::STATUS_RUNNING, $workerName, $method);
0 ignored issues
show
Bug introduced by
It seems like countJobsByStatus() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

69
        /** @scrutinizer ignore-call */ 
70
        $count = $this->countJobsByStatus($this->getJobClass(), BaseJob::STATUS_RUNNING, $workerName, $method);
Loading history...
70
71 4
        $criterion = ['status' => BaseJob::STATUS_RUNNING];
72 4
        $this->addWorkerNameMethod($criterion, $workerName, $method);
0 ignored issues
show
Bug introduced by
It seems like addWorkerNameMethod() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

72
        $this->/** @scrutinizer ignore-call */ 
73
               addWorkerNameMethod($criterion, $workerName, $method);
Loading history...
73
74 4
        $runningJobs = $this->findRunningJobs($criterion, $count);
75
76 4
        return $this->extractStalledJobs($runningJobs);
77
    }
78
79
    /**
80
     * @param StallableJob $jobArchive
81
     *
82
     * @return int Number of jobs reset
83
     */
84 2
    protected function resetArchiveJob(StallableJob $jobArchive)
85
    {
86 2
        $objectManager = $this->getObjectManager();
87 2
        if ($this->updateMaxStatus($jobArchive, StallableJob::STATUS_MAX_RETRIES, $jobArchive->getMaxRetries(), $jobArchive->getRetries())) {
0 ignored issues
show
Bug introduced by
It seems like updateMaxStatus() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

87
        if ($this->/** @scrutinizer ignore-call */ updateMaxStatus($jobArchive, StallableJob::STATUS_MAX_RETRIES, $jobArchive->getMaxRetries(), $jobArchive->getRetries())) {
Loading history...
88 2
            $objectManager->persist($jobArchive);
89
90 2
            return 0;
91
        }
92
93
        /** @var StallableJob $job */
94 2
        $className = $this->getJobClass();
95 2
        $newJob = new $className();
96 2
        Util::copy($jobArchive, $newJob);
97 2
        $this->resetJob($newJob);
0 ignored issues
show
Bug introduced by
The method resetJob() does not exist on Dtc\QueueBundle\Doctrine\StalledTrait. Did you maybe mean resetJobsByCriterion()? ( Ignorable by Annotation )

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

97
        $this->/** @scrutinizer ignore-call */ 
98
               resetJob($newJob);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
98 2
        $objectManager->remove($jobArchive);
99 2
        $this->flush();
0 ignored issues
show
Bug introduced by
It seems like flush() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

99
        $this->/** @scrutinizer ignore-call */ 
100
               flush();
Loading history...
100
101 2
        return 1;
102
    }
103
104 4
    protected function findRunningJobs($criterion, $count)
105
    {
106 4
        $repository = $this->getRepository();
0 ignored issues
show
Bug introduced by
It seems like getRepository() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

106
        /** @scrutinizer ignore-call */ 
107
        $repository = $this->getRepository();
Loading history...
107 4
        $runningJobsById = [];
108
109 4
        $metadata = $this->getObjectManager()->getClassMetadata($this->getJobClass());
110 4
        $identifierData = $metadata->getIdentifier();
111 4
        $idColumn = isset($identifierData[0]) ? $identifierData[0] : 'id';
112
113 4
        $fetchCount = $this->getFetchCount($count);
0 ignored issues
show
Bug introduced by
It seems like getFetchCount() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

113
        /** @scrutinizer ignore-call */ 
114
        $fetchCount = $this->getFetchCount($count);
Loading history...
114 4
        for ($i = 0; $i < $count; $i += $fetchCount) {
115 4
            $runningJobs = $repository->findBy($criterion, [$idColumn => 'ASC'], $fetchCount, $i);
116 4
            if (!empty($runningJobs)) {
117 4
                foreach ($runningJobs as $job) {
118
                    /** @var StallableJob $job */
119 4
                    $runId = $job->getRunId();
120 4
                    $runningJobsById[$runId][] = $job;
121
                }
122
            }
123
        }
124
125 4
        return $runningJobsById;
126
    }
127
128 4
    private function extractStalledJobsRunArchive(array $runningJobsById, array &$stalledJobs, $runId)
129
    {
130 4
        $runManager = $this->getRunManager();
0 ignored issues
show
Bug introduced by
It seems like getRunManager() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

130
        /** @scrutinizer ignore-call */ 
131
        $runManager = $this->getRunManager();
Loading history...
131 4
        if (!method_exists($runManager, 'getObjectManager')) {
132
            return;
133
        }
134 4
        if (!method_exists($runManager, 'getRunArchiveClass')) {
135
            return;
136
        }
137
138
        /** @var EntityRepository|DocumentRepository $runArchiveRepository */
139 4
        $runArchiveRepository = $runManager->getObjectManager()->getRepository($runManager->getRunArchiveClass());
140
        /** @var Run $run */
141 4
        if ($run = $runArchiveRepository->find($runId)) {
142 4
            if ($endTime = $run->getEndedAt()) {
143
                // Did it end over an hour ago
144 4
                if ((time() - $endTime->getTimestamp()) > static::STALLED_SECONDS) {
0 ignored issues
show
Bug introduced by
The constant Dtc\QueueBundle\Doctrine...dTrait::STALLED_SECONDS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
145 4
                    $stalledJobs = array_merge($stalledJobs, $runningJobsById[$runId]);
146
                }
147
            }
148
        }
149 4
    }
150
151
    /**
152
     * @param array $runningJobsById
153
     *
154
     * @return array
155
     */
156 4
    private function extractStalledJobs(array $runningJobsById)
157
    {
158 4
        $stalledJobs = [];
159 4
        foreach (array_keys($runningJobsById) as $runId) {
160 4
            if (!$runId && 0 !== $runId) {
161 2
                $stalledJobs = array_merge($stalledJobs, $runningJobsById[$runId]);
162 2
                continue;
163
            }
164 4
            $this->extractStalledLiveRuns($runId, $runningJobsById[$runId], $stalledJobs);
165 4
            $this->extractStalledJobsRunArchive($runningJobsById, $stalledJobs, $runId);
166
        }
167
168 4
        return $stalledJobs;
169
    }
170
171
    /**
172
     * @param $runId
173
     * @param array $jobs
174
     * @param array $stalledJobs
175
     */
176 4
    private function extractStalledLiveRuns($runId, array $jobs, array &$stalledJobs)
177
    {
178 4
        $objectManager = $this->getObjectManager();
179 4
        $runRepository = $objectManager->getRepository($this->getRunManager()->getRunClass());
180 4
        if ($run = $runRepository->find($runId)) {
181 2
            foreach ($jobs as $job) {
182 2
                if ($run->getCurrentJobId() == $job->getId()) {
183 2
                    continue;
184
                }
185 2
                $stalledJobs[] = $job;
186
            }
187
        }
188 4
    }
189
}
190