Completed
Pull Request — master (#30)
by Matthew
14:09 queued 11:28
created

JobManager::takeJob()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 27
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 3.0015

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 17
cts 18
cp 0.9444
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 19
nc 4
nop 2
crap 3.0015
1
<?php
2
3
namespace Dtc\QueueBundle\ORM;
4
5
use Doctrine\ORM\EntityManager;
6
use Doctrine\ORM\EntityRepository;
7
use Doctrine\ORM\QueryBuilder;
8
use Dtc\QueueBundle\Doctrine\DoctrineJobManager;
9
use Dtc\QueueBundle\Entity\Job;
10
use Dtc\QueueBundle\Model\BaseJob;
11
use Dtc\QueueBundle\Model\RetryableJob;
12
use Dtc\QueueBundle\Model\StallableJob;
13
use Dtc\QueueBundle\Util\Util;
14
use Symfony\Component\Process\Exception\LogicException;
15
16
class JobManager extends DoctrineJobManager
17
{
18
    use CommonTrait;
19
    protected static $saveInsertCalled = null;
20
    protected static $resetInsertCalled = null;
21
22 3
    public function countJobsByStatus($objectName, $status, $workerName = null, $method = null)
23
    {
24
        /** @var EntityManager $objectManager */
25 3
        $objectManager = $this->getObjectManager();
26
27
        $queryBuilder = $objectManager
28 3
            ->createQueryBuilder()
29 3
            ->select('count(a.id)')
30 3
            ->from($objectName, 'a')
31 3
            ->where('a.status = :status');
32
33 3
        if (null !== $workerName) {
34 1
            $queryBuilder->andWhere('a.workerName = :workerName')
35 1
                ->setParameter(':workerName', $workerName);
36 1
        }
37
38 3
        if (null !== $method) {
39 1
            $queryBuilder->andWhere('a.method = :method')
40 1
                ->setParameter(':method', $workerName);
41 1
        }
42
43 3
        $count = $queryBuilder->setParameter(':status', $status)
44 3
            ->getQuery()->getSingleScalarResult();
45
46 3
        if (!$count) {
47 1
            return 0;
48
        }
49
50 3
        return $count;
51
    }
52
53
    /**
54
     * @param string|null $workerName
55
     * @param string|null $method
56
     *
57
     * @return int Count of jobs pruned
58
     */
59 1
    public function pruneExceptionJobs($workerName = null, $method = null)
60
    {
61
        /** @var EntityManager $objectManager */
62 1
        $objectManager = $this->getObjectManager();
63 1
        $queryBuilder = $objectManager->createQueryBuilder()->delete($this->getJobArchiveClass(), 'j');
64 1
        $queryBuilder->where('j.status = :status')
65 1
            ->setParameter(':status', BaseJob::STATUS_EXCEPTION);
66
67 1
        $this->addWorkerNameCriterion($queryBuilder, $workerName, $method);
68 1
        $query = $queryBuilder->getQuery();
69
70 1
        return intval($query->execute());
71
    }
72
73 21
    protected function resetSaveOk($function)
74
    {
75 21
        $objectManager = $this->getObjectManager();
76 21
        $splObjectHash = spl_object_hash($objectManager);
77
78 21
        if ('save' === $function) {
79
            $compare = static::$resetInsertCalled;
80
        } else {
81 21
            $compare = static::$saveInsertCalled;
82
        }
83
84 21
        if ($splObjectHash === $compare) {
85
            // Insert SQL is cached...
86
            $msg = "Can't call save and reset within the same process cycle (or using the same EntityManager)";
87
            throw new LogicException($msg);
88
        }
89
90 21
        if ('save' === $function) {
91
            static::$saveInsertCalled = spl_object_hash($objectManager);
92
        } else {
93 21
            static::$resetInsertCalled = spl_object_hash($objectManager);
94
        }
95 21
    }
96
97
    /**
98
     * @param string $workerName
99
     * @param string $method
100
     */
101 13
    protected function addWorkerNameCriterion(QueryBuilder $queryBuilder, $workerName = null, $method = null)
102
    {
103 13
        if (null !== $workerName) {
104 5
            $queryBuilder->andWhere('j.workerName = :workerName')->setParameter(':workerName', $workerName);
105 5
        }
106
107 13
        if (null !== $method) {
108 4
            $queryBuilder->andWhere('j.method = :method')->setParameter(':method', $method);
109 4
        }
110 13
    }
111
112 1
    protected function updateExpired($workerName = null, $method = null)
113
    {
114
        /** @var EntityManager $objectManager */
115 1
        $objectManager = $this->getObjectManager();
116 1
        $queryBuilder = $objectManager->createQueryBuilder()->update($this->getJobClass(), 'j');
117 1
        $queryBuilder->set('j.status', ':newStatus');
118 1
        $queryBuilder->where('j.expiresAt <= :expiresAt')
119 1
            ->setParameter(':expiresAt', Util::getMicrotimeDateTime());
120 1
        $queryBuilder->andWhere('j.status = :status')
121 1
            ->setParameter(':status', BaseJob::STATUS_NEW)
122 1
            ->setParameter(':newStatus', Job::STATUS_EXPIRED);
123
124 1
        $this->addWorkerNameCriterion($queryBuilder, $workerName, $method);
125 1
        $query = $queryBuilder->getQuery();
126
127 1
        return intval($query->execute());
128
    }
129
130
    /**
131
     * Removes archived jobs older than $olderThan.
132
     *
133
     * @param \DateTime $olderThan
134
     */
135 1
    public function pruneArchivedJobs(\DateTime $olderThan)
136
    {
137 1
        return $this->removeOlderThan(
138 1
            $this->getJobArchiveClass(),
139 1
                'updatedAt',
140
                $olderThan
141 1
        );
142
    }
143
144 2
    public function getJobCount($workerName = null, $method = null)
145
    {
146
        /** @var EntityManager $objectManager */
147 2
        $objectManager = $this->getObjectManager();
148 2
        $queryBuilder = $objectManager->createQueryBuilder();
149
150 2
        $queryBuilder = $queryBuilder->select('count(j)')->from($this->getJobClass(), 'j');
151
152 2
        $where = 'where';
153 2
        if (null !== $workerName) {
154
            if (null !== $method) {
155
                $queryBuilder->where($queryBuilder->expr()->andX(
156
                    $queryBuilder->expr()->eq('j.workerName', ':workerName'),
157
                                                $queryBuilder->expr()->eq('j.method', ':method')
158
                ))
159
                    ->setParameter(':method', $method);
160
            } else {
161
                $queryBuilder->where('j.workerName = :workerName');
162
            }
163
            $queryBuilder->setParameter(':workerName', $workerName);
164
            $where = 'andWhere';
165 2
        } elseif (null !== $method) {
166
            $queryBuilder->where('j.method = :method')->setParameter(':method', $method);
167
            $where = 'andWhere';
168
        }
169
170
        // Filter
171
        $queryBuilder
172 2
            ->$where($queryBuilder->expr()->orX(
173 2
                $queryBuilder->expr()->isNull('j.whenUs'),
174 2
                                        $queryBuilder->expr()->lte('j.whenUs', ':whenUs')
175 2
            ))
176 2
            ->andWhere($queryBuilder->expr()->orX(
177 2
                $queryBuilder->expr()->isNull('j.expiresAt'),
178 2
                $queryBuilder->expr()->gt('j.expiresAt', ':expiresAt')
179 2
            ))
180 2
            ->setParameter(':whenUs', Util::getMicrotimeDecimal())
181 2
            ->setParameter(':expiresAt', Util::getMicrotimeDateTime());
182
183 2
        $query = $queryBuilder->getQuery();
184
185 2
        return $query->getSingleScalarResult();
186
    }
187
188
    /**
189
     * Get Jobs statuses.
190
     */
191 3
    public function getStatus()
192
    {
193 3
        $result = [];
194 3
        $this->getStatusByEntityName($this->getJobClass(), $result);
195 3
        $this->getStatusByEntityName($this->getJobArchiveClass(), $result);
196
197 3
        $finalResult = [];
198 3
        foreach ($result as $key => $item) {
199 1
            ksort($item);
200 1
            foreach ($item as $status => $count) {
201 1
                if (isset($finalResult[$key][$status])) {
202
                    $finalResult[$key][$status] += $count;
203
                } else {
204 1
                    $finalResult[$key][$status] = $count;
205
                }
206 1
            }
207 3
        }
208
209 3
        return $finalResult;
210
    }
211
212
    /**
213
     * @param string $entityName
214
     */
215 3
    protected function getStatusByEntityName($entityName, array &$result)
216
    {
217
        /** @var EntityManager $objectManager */
218 3
        $objectManager = $this->getObjectManager();
219 3
        $result1 = $objectManager->getRepository($entityName)->createQueryBuilder('j')->select('j.workerName, j.method, j.status, count(j) as c')
220 3
            ->groupBy('j.workerName, j.method, j.status')->getQuery()->getArrayResult();
221
222 3
        foreach ($result1 as $item) {
223 1
            $method = $item['workerName'].'->'.$item['method'].'()';
224 1
            if (!isset($result[$method])) {
225 1
                $result[$method] = [BaseJob::STATUS_NEW => 0,
226 1
                    BaseJob::STATUS_RUNNING => 0,
227 1
                    BaseJob::STATUS_SUCCESS => 0,
228 1
                    BaseJob::STATUS_FAILURE => 0,
229 1
                    BaseJob::STATUS_EXCEPTION => 0,
230 1
                    StallableJob::STATUS_STALLED => 0,
231 1
                    \Dtc\QueueBundle\Model\Job::STATUS_EXPIRED => 0,
232 1
                    RetryableJob::STATUS_MAX_FAILURES => 0,
233 1
                    RetryableJob::STATUS_MAX_EXCEPTIONS => 0,
234 1
                    StallableJob::STATUS_MAX_STALLS => 0,
235 1
                    RetryableJob::STATUS_MAX_RETRIES => 0, ];
236 1
            }
237 1
            $result[$method][$item['status']] += intval($item['c']);
238 3
        }
239 3
    }
240
241
    /**
242
     * Get the next job to run (can be filtered by workername and method name).
243
     *
244
     * @param string $workerName
245
     * @param string $methodName
246
     * @param bool   $prioritize
247
     * @param int    $runId
248
     *
249
     * @return Job|null
250
     */
251 11
    public function getJob($workerName = null, $methodName = null, $prioritize = true, $runId = null)
252
    {
253
        do {
254 11
            $queryBuilder = $this->getJobQueryBuilder($workerName, $methodName, $prioritize);
255 11
            $queryBuilder->select('j.id');
256 11
            $queryBuilder->setMaxResults(100);
257
258
            /** @var QueryBuilder $queryBuilder */
259 11
            $query = $queryBuilder->getQuery();
260 11
            $jobs = $query->getResult();
261 11
            if ($jobs) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $jobs of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
262 9
                foreach ($jobs as $job) {
263 9
                    if ($job = $this->takeJob($job['id'], $runId)) {
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $job is correct as $this->takeJob($job['id'], $runId) (which targets Dtc\QueueBundle\ORM\JobManager::takeJob()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
264 9
                        return $job;
265
                    }
266
                }
267
            }
268 6
        } while ($jobs);
0 ignored issues
show
Bug Best Practice introduced by
The expression $jobs of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
269
270 6
        return null;
271
    }
272
273
    /**
274
     * @param string|null $workerName
275
     * @param string|null $methodName
276
     * @param bool        $prioritize
277
     *
278
     * @return QueryBuilder
279
     */
280 11
    public function getJobQueryBuilder($workerName = null, $methodName = null, $prioritize = true)
281
    {
282
        /** @var EntityRepository $repository */
283 11
        $repository = $this->getRepository();
284 11
        $queryBuilder = $repository->createQueryBuilder('j');
285 11
        $this->addStandardPredicate($queryBuilder);
286 11
        $this->addWorkerNameCriterion($queryBuilder, $workerName, $methodName);
287
288 11
        if ($prioritize) {
289 11
            $queryBuilder->addOrderBy('j.priority', 'DESC');
290 11
            $queryBuilder->addOrderBy('j.whenUs', 'ASC');
291 11
        } else {
292 1
            $queryBuilder->orderBy('j.whenUs', 'ASC');
293
        }
294
295 11
        return $queryBuilder;
296
    }
297
298 12
    protected function addStandardPredicate(QueryBuilder $queryBuilder)
299
    {
300 12
        $dateTime = Util::getMicrotimeDateTime();
301 12
        $decimal = Util::getMicrotimeDecimalFormat($dateTime);
302
303
        $queryBuilder
304 12
            ->where('j.status = :status')->setParameter(':status', BaseJob::STATUS_NEW)
305 12
            ->andWhere($queryBuilder->expr()->orX(
306 12
                $queryBuilder->expr()->isNull('j.whenUs'),
307 12
                $queryBuilder->expr()->lte('j.whenUs', ':whenUs')
308 12
            ))
309 12
            ->andWhere($queryBuilder->expr()->orX(
310 12
                $queryBuilder->expr()->isNull('j.expiresAt'),
311 12
                $queryBuilder->expr()->gt('j.expiresAt', ':expiresAt')
312 12
            ))
313 12
            ->setParameter(':whenUs', $decimal)
314 12
            ->setParameter(':expiresAt', $dateTime);
315 12
    }
316
317
    /**
318
     * @param int $runId
319
     */
320 9
    protected function takeJob($jobId, $runId = null)
321
    {
322
        /** @var EntityRepository $repository */
323 9
        $repository = $this->getRepository();
324
        /** @var QueryBuilder $queryBuilder */
325 9
        $queryBuilder = $repository->createQueryBuilder('j');
326
        $queryBuilder
327 9
            ->update()
328 9
            ->set('j.status', ':status')
329 9
            ->setParameter(':status', BaseJob::STATUS_RUNNING);
330 9
        if (null !== $runId) {
331
            $queryBuilder
332 1
                ->set('j.runId', ':runId')
333 1
                ->setParameter(':runId', $runId);
334 2
        }
335 9
        $queryBuilder->set('j.startedAt', ':startedAt')
336 9
            ->setParameter(':startedAt', Util::getMicrotimeDateTime());
337 9
        $queryBuilder->where('j.id = :id');
338 9
        $queryBuilder->setParameter(':id', $jobId);
339 9
        $resultCount = $queryBuilder->getQuery()->execute();
340
341 9
        if (1 === $resultCount) {
342 9
            return $repository->find($jobId);
343
        }
344
345
        return null;
346
    }
347
348
    /**
349
     * Tries to update the nearest job as a batch.
350
     *
351
     * @param \Dtc\QueueBundle\Model\Job $job
352
     *
353
     * @return null|Job
354
     */
355 1
    public function updateNearestBatch(\Dtc\QueueBundle\Model\Job $job)
356
    {
357
        /** @var QueryBuilder $queryBuilder */
358 1
        $queryBuilder = $this->getRepository()->createQueryBuilder('j');
359 1
        $queryBuilder->select()
360 1
            ->where('j.crcHash = :crcHash')
361 1
            ->andWhere('j.status = :status')
362 1
            ->setParameter(':status', BaseJob::STATUS_NEW)
363 1
            ->setParameter(':crcHash', $job->getCrcHash())
364 1
            ->orderBy('j.whenUs', 'ASC')
365 1
            ->setMaxResults(1);
366 1
        $existingJobs = $queryBuilder->getQuery()->execute();
367
368 1
        if (empty($existingJobs)) {
369
            return null;
370
        }
371
        /** @var Job $existingJob */
372 1
        $existingJob = $existingJobs[0];
373
374 1
        $newPriority = max($job->getPriority(), $existingJob->getPriority());
375 1
        $newWhenUs = $existingJob->getWhenUs();
376 1
        $bcResult = bccomp($job->getWhenUs(), $existingJob->getWhenUs());
0 ignored issues
show
Documentation Bug introduced by
The method getWhenUs does not exist on object<Dtc\QueueBundle\Model\Job>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
377 1
        if ($bcResult < 0) {
378 1
            $newWhenUs = $job->getWhenUs();
0 ignored issues
show
Documentation Bug introduced by
The method getWhenUs does not exist on object<Dtc\QueueBundle\Model\Job>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
379 1
        }
380
381 1
        $this->updateBatchJob($existingJob, $newPriority, $newWhenUs);
382
383 1
        return $existingJob;
384
    }
385
386
    /**
387
     * @param int    $newPriority
388
     * @param string $newWhenUs
389
     */
390 1
    protected function updateBatchJob(Job $existingJob, $newPriority, $newWhenUs)
391
    {
392 1
        $existingPriority = $existingJob->getPriority();
393 1
        $existingWhenUs = $existingJob->getWhenUs();
394
395 1
        if ($newPriority !== $existingPriority || $newWhenUs !== $existingWhenUs) {
396
            /** @var EntityRepository $repository */
397 1
            $repository = $this->getRepository();
398
            /** @var QueryBuilder $queryBuilder */
399 1
            $queryBuilder = $repository->createQueryBuilder('j');
400 1
            $queryBuilder->update();
401 1
            if ($newPriority !== $existingPriority) {
402 1
                $existingJob->setPriority($newPriority);
403 1
                $queryBuilder->set('j.priority', ':priority')
404 1
                    ->setParameter(':priority', $newPriority);
405 1
            }
406 1
            if ($newWhenUs !== $existingWhenUs) {
407 1
                $existingJob->setWhenUs($newWhenUs);
408 1
                $queryBuilder->set('j.whenUs', ':whenUs')
409 1
                    ->setParameter(':whenUs', $newWhenUs);
410 1
            }
411 1
            $queryBuilder->where('j.id = :id');
412 1
            $queryBuilder->setParameter(':id', $existingJob->getId());
413 1
            $queryBuilder->getQuery()->execute();
414 1
        }
415
416 1
        return $existingJob;
417
    }
418
419 1
    public function getWorkersAndMethods()
420
    {
421
        /** @var EntityRepository $repository */
422 1
        $repository = $this->getRepository();
423 1
        $queryBuilder = $repository->createQueryBuilder('j');
424 1
        $this->addStandardPredicate($queryBuilder);
425
        $queryBuilder
426 1
            ->select('DISTINCT j.workerName, j.method');
427
428 1
        $results = $queryBuilder->getQuery()->getArrayResult();
429 1
        if (!$results) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $results of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
430 1
            return [];
431
        }
432
        $workerMethods = [];
433
        foreach ($results as $result) {
434
            $workerMethods[$result['workerName']][] = $result['method'];
435
        }
436
437
        return $workerMethods;
438
    }
439
440
    /**
441
     * @param string $workerName
442
     * @param string $methodName
443
     */
444 2
    public function countLiveJobs($workerName = null, $methodName = null)
445
    {
446
        /** @var EntityRepository $repository */
447 2
        $repository = $this->getRepository();
448 2
        $queryBuilder = $repository->createQueryBuilder('j');
449 2
        $this->addStandardPredicate($queryBuilder);
450 2
        $this->addWorkerNameCriterion($queryBuilder, $workerName, $methodName);
451 2
        $queryBuilder->select('count(j.id)');
452
453 2
        return $queryBuilder->getQuery()->getSingleScalarResult();
454
    }
455
456
    /**
457
     * @param string   $workerName
458
     * @param string   $methodName
459
     * @param \Closure $progressCallback
460
     */
461 1
    public function archiveAllJobs($workerName = null, $methodName = null, $progressCallback)
462
    {
463
        // First mark all Live non-running jobs as Archive
464 1
        $repository = $this->getRepository();
465
        /** @var QueryBuilder $queryBuilder */
466 1
        $queryBuilder = $repository->createQueryBuilder('j');
467 1
        $queryBuilder->update($this->getJobClass(), 'j')
468 1
            ->set('j.status', ':statusArchive')
469 1
            ->setParameter(':statusArchive', Job::STATUS_ARCHIVE);
470 1
        $this->addStandardPredicate($queryBuilder);
471 1
        $this->addWorkerNameCriterion($queryBuilder, $workerName, $methodName);
472 1
        $resultCount = $queryBuilder->getQuery()->execute();
473
474 1
        if ($resultCount) {
475 1
            $this->runArchive($workerName, $methodName, $progressCallback);
476 1
        }
477 1
    }
478
479
    /**
480
     * Move jobs in 'archive' status to the archive table.
481
     *
482
     *  This is a bit of a hack to run a lower level query so as to process the INSERT INTO SELECT
483
     *   All on the server as "INSERT INTO SELECT" is not supported natively in Doctrine.
484
     *
485
     * @param string|null $workerName
486
     * @param string|null $methodName
487
     * @param \Closure    $progressCallback
488
     */
489 1
    protected function runArchive($workerName = null, $methodName = null, $progressCallback)
0 ignored issues
show
Unused Code introduced by
The parameter $workerName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $methodName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
490
    {
491
        /** @var EntityManager $entityManager */
492 1
        $entityManager = $this->getObjectManager();
493 1
        $count = 0;
494
        do {
495
            /** @var EntityRepository $repository */
496 1
            $repository = $this->getRepository();
497 1
            $queryBuilder = $repository->createQueryBuilder('j');
498 1
            $queryBuilder->where('j.status = :status')
499 1
                ->setParameter(':status', Job::STATUS_ARCHIVE)
500 1
                ->setMaxResults(10000);
501
502 1
            $results = $queryBuilder->getQuery()->getArrayResult();
503 1
            foreach ($results as $jobRow) {
504 1
                $job = $repository->find($jobRow['id']);
505 1
                if ($job) {
506 1
                    $entityManager->remove($job);
507 1
                }
508 1
                ++$count;
509 1
                if (0 == $count % 10) {
510
                    $this->flush();
511
                    $progressCallback($count);
512
                }
513 1
            }
514 1
            $this->flush();
515 1
            $progressCallback($count);
516 1
        } while ($results && 10000 == count($results));
0 ignored issues
show
Bug Best Practice introduced by
The expression $results of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
517 1
    }
518
}
519