Completed
Pull Request — master (#30)
by Matthew
07:24
created

DoctrineJobManagerTest::testPruneStalledJobs()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 152
Code Lines 115

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 152
rs 8.2857
c 0
b 0
f 0
cc 1
eloc 115
nc 1
nop 0

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\Tests\Doctrine;
4
5
use Doctrine\ODM\MongoDB\DocumentManager;
6
use Doctrine\ORM\EntityManager;
7
use Dtc\QueueBundle\Doctrine\DoctrineJobManager;
8
use Dtc\QueueBundle\Doctrine\DtcQueueListener;
9
use Dtc\QueueBundle\Model\BaseJob;
10
use Dtc\QueueBundle\Model\Job;
11
use Dtc\QueueBundle\Model\RetryableJob;
12
use Dtc\QueueBundle\Tests\Manager\AutoRetryTrait;
13
use Dtc\QueueBundle\Tests\Manager\PriorityTestTrait;
14
use Dtc\QueueBundle\Model\StallableJob;
15
use Dtc\QueueBundle\Tests\FibonacciWorker;
16
use Dtc\QueueBundle\Tests\Manager\BaseJobManagerTest;
17
use Dtc\QueueBundle\ODM\JobManager;
18
use Dtc\QueueBundle\Tests\ORM\JobManagerTest;
19
use Dtc\QueueBundle\Util\Util;
20
use Symfony\Component\DependencyInjection\Container;
21
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
22
23
/**
24
 * @author David
25
 *
26
 * This test requires local mongodb running
27
 */
28
abstract class DoctrineJobManagerTest extends BaseJobManagerTest
29
{
30
    use PriorityTestTrait;
31
    use AutoRetryTrait;
32
33
    protected static $dtcQueueListener;
34
35
    /** @var DocumentManager|EntityManager */
36
    protected static $objectManager;
37
    protected static $objectName;
38
    protected static $archiveObjectName;
39
    protected static $runClass;
40
    protected static $runArchiveClass;
41
    protected static $jobTimingClass;
42
    protected static $jobManagerClass;
43
    protected static $runManagerClass;
44
    protected static $jobTimingManagerClass;
45
    public static $runManager;
46
47
    public static function setUpBeforeClass()
48
    {
49
        self::$jobTimingManager = new self::$jobTimingManagerClass(self::$objectManager, self::$jobTimingClass, true);
50
        self::$runManager = new self::$runManagerClass(self::$objectManager, self::$runClass, self::$runArchiveClass);
51
        self::$jobManager = new self::$jobManagerClass(self::$runManager, self::$jobTimingManager, self::$objectManager, self::$objectName, self::$archiveObjectName);
52
        self::$jobManager->setMaxPriority(255);
53
54
        self::assertEquals(255, self::$jobManager->getMaxPriority());
55
        self::assertEquals(JobManager::PRIORITY_DESC, self::$jobManager->getPriorityDirection());
56
        self::$jobManager->setPriorityDirection(JobManager::PRIORITY_ASC);
57
        self::assertEquals(JobManager::PRIORITY_ASC, self::$jobManager->getPriorityDirection());
58
        self::$jobManager->setPriorityDirection(JobManager::PRIORITY_DESC);
59
60
        /** @var DoctrineJobManager $jobManager */
61
        $jobManager = self::$jobManager;
62
63
        $parameters = new ParameterBag();
64
65
        $container = new Container($parameters);
66
        $container->set('dtc_queue.job_manager', $jobManager);
67
        $container->set('dtc_queue.run_manager', self::$runManager);
68
69
        self::$dtcQueueListener = new DtcQueueListener(self::$jobManager->getJobArchiveClass(), self::$runManager->getRunArchiveClass());
70
        self::$objectManager->getEventManager()->addEventListener('preUpdate', self::$dtcQueueListener);
71
        self::$objectManager->getEventManager()->addEventListener('prePersist', self::$dtcQueueListener);
72
        self::$objectManager->getEventManager()->addEventListener('preRemove', self::$dtcQueueListener);
73
74
        self::$worker = new FibonacciWorker();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Dtc\QueueBundle\Tests\FibonacciWorker() of type object<Dtc\QueueBundle\Tests\FibonacciWorker> is incompatible with the declared type object<Dtc\QueueBundle\Manager\Worker> of property $worker.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
75
76
        parent::setUpBeforeClass();
77
    }
78
79
    public static function tearDownAfterClass()
80
    {
81
        self::$objectManager->getEventManager()->removeEventListener('preUpdate', self::$dtcQueueListener);
82
        self::$objectManager->getEventManager()->removeEventListener('prePersist', self::$dtcQueueListener);
83
        self::$objectManager->getEventManager()->removeEventListener('preRemove', self::$dtcQueueListener);
84
        parent::tearDownAfterClass();
85
    }
86
87
    public function testOrdering()
88
    {
89
        // priority when at
90
        /** @var DoctrineJobManager $jobManager */
91
        $jobManager = self::$jobManager;
92
93
        $time1 = time() - 2;
94
        $dateTime1 = new \DateTime("@$time1");
95
96
        $time2 = time();
97
        $dateTime2 = new \DateTime("@$time2");
98
99
        /** @var Job $job */
100
        $job = new static::$jobClass(static::$worker, false, null);
101
        $job->fibonacci(1);
0 ignored issues
show
Documentation Bug introduced by
The method fibonacci 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...
102
        $job->setWhenAt($dateTime1);
103
        $job->setPriority(3);
104
        $id = $job->getId();
105
106
        $job2 = new static::$jobClass(static::$worker, false, null);
107
        $job2->setPriority(1);
108
        $job2->setWhenAt($dateTime2);
109
        $job2->fibonacci(1);
110
        $id2 = $job2->getId();
111
112
        $job3 = new static::$jobClass(static::$worker, false, null);
113
        $job3->setPriority(1);
114
        $job3->setWhenAt($dateTime1);
115
        $job3->fibonacci(1);
116
        $id3 = $job3->getId();
117
118
        $job4 = new static::$jobClass(static::$worker, false, null);
119
        $job4->setPriority(1);
120
        $job4->setWhenAt($dateTime2);
121
        $job4->fibonacci(1);
122
        $id4 = $job4->getId();
123
124
        $nextJob = $jobManager->getJob();
125
        static::assertEquals($id3, $nextJob->getId());
126
        $nextNextJob = $jobManager->getJob();
127
        $nextNextId = $nextNextJob->getId();
128
        static::assertTrue($id4 == $nextNextId || $id2 == $nextNextId, "$nextNextId not equals $id4 or $id2, could be $id or $id3");
129
130
        static::assertNotNull($jobManager->getJob());
131
        static::assertNotNull($jobManager->getJob());
132
133
        // non-priority when at
134
        $time1 = time() - 2;
135
        $dateTime1 = new \DateTime("@$time1");
136
137
        $time2 = time();
138
        $dateTime2 = new \DateTime("@$time2");
139
140
        /** @var Job $job */
141
        $job = new static::$jobClass(static::$worker, false, null);
142
        $job->fibonacci(1);
0 ignored issues
show
Documentation Bug introduced by
The method fibonacci 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...
143
        $job->setWhenAt($dateTime1);
144
        $job->setPriority(3);
145
        $id = $job->getId();
146
147
        $job2 = new static::$jobClass(static::$worker, false, null);
148
        $job2->setPriority(1);
149
        $job2->setWhenAt($dateTime2);
150
        $job2->fibonacci(1);
151
152
        $job3 = new static::$jobClass(static::$worker, false, null);
153
        $job3->setPriority(1);
154
        $job3->setWhenAt($dateTime2);
155
        $job3->fibonacci(1);
156
157
        $job4 = new static::$jobClass(static::$worker, false, null);
158
        $job4->setPriority(1);
159
        $job4->setWhenAt($dateTime2);
160
        $job4->fibonacci(1);
161
162
        $nextJob = $jobManager->getJob(null, null, false);
163
        static::assertEquals($id, $nextJob->getId());
164
        static::assertNotNull($jobManager->getJob());
165
        static::assertNotNull($jobManager->getJob());
166
        static::assertNotNull($jobManager->getJob());
167
    }
168
169
    public function getJobBy()
170
    {
171
        /** @var DoctrineJobManager $jobManager */
172
        $jobManager = self::$jobManager;
173
174
        /** @var Job $job */
175
        $job = new static::$jobClass(static::$worker, false, null);
176
        $job->fibonacci(1);
0 ignored issues
show
Documentation Bug introduced by
The method fibonacci 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...
177
        $id = $job->getId();
178
        $nextJob = $jobManager->getJob('fibonacci', null);
179
        static::assertNotNull($nextJob);
180
        static::assertEquals($id, $nextJob->getId());
181
182
        /** @var Job $job */
183
        $job = new static::$jobClass(static::$worker, false, null);
184
        $job->fibonacci(1);
0 ignored issues
show
Documentation Bug introduced by
The method fibonacci 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...
185
        $id = $job->getId();
186
        $nextJob = $jobManager->getJob('fibonacci', 'fibonacci');
187
        static::assertNotNull($nextJob);
188
        static::assertEquals($id, $nextJob->getId());
189
190
        /** @var Job $job */
191
        $job = new static::$jobClass(static::$worker, false, null);
192
        $job->fibonacci(1);
0 ignored issues
show
Documentation Bug introduced by
The method fibonacci 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...
193
        $id = $job->getId();
194
        $nextJob = $jobManager->getJob(null, 'fibonacci');
195
        static::assertNotNull($nextJob);
196
        static::assertEquals($id, $nextJob->getId());
197
198
        /** @var Job $job */
199
        $job = new static::$jobClass(static::$worker, false, null);
200
        $job->fibonacci(1);
0 ignored issues
show
Documentation Bug introduced by
The method fibonacci 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...
201
        $id = $job->getId();
202
        $nextJob = $jobManager->getJob(null, 'fibonaccia');
203
        static::assertNull($nextJob);
204
        $nextJob = $jobManager->getJob('fibonacci', 'fibonaccia');
205
        static::assertNull($nextJob);
206
        $nextJob = $jobManager->getJob('fibonaccii', 'fibonacci');
207
        static::assertNull($nextJob);
208
        $nextJob = $jobManager->getJob();
209
        static::assertNotNull($nextJob);
210
        static::assertEquals($id, $nextJob->getId());
211
    }
212
213
    public function testDeleteJob()
214
    {
215
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
216
        $jobManager = self::$jobManager;
217
218
        /** @var Job $job */
219
        $job = $this->getJob();
220
        $id = $job->getId();
221
        $jobManager->deleteJob($job);
222
223
        $nextJob = $jobManager->getJob(null, null, true, 123);
224
        self::assertNull($nextJob, "Shouldn't be any jobs left in queue");
225
226
        $archiveObjectName = $jobManager->getJobArchiveClass();
227
228
        self::assertNotNull($id);
229
        $archiveRepository = $jobManager->getObjectManager()->getRepository($archiveObjectName);
230
        $result = $archiveRepository->find($id);
231
        self::assertNotNull($result);
232
        self::assertEquals($id, $result->getId());
233
    }
234
235
    public function testCountLiveJobs()
236
    {
237
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
238
        $jobManager = self::$jobManager;
239
240
        while ($job = $jobManager->getJob()) {
241
            $jobManager->deleteJob($job);
242
        }
243
244
        $this->getJob();
245
246
        $count = $jobManager->countLiveJobs();
247
        self::assertEquals(1, $count);
248
249
        $this->getJob();
250
251
        $count = $jobManager->countLiveJobs();
252
        self::assertEquals(2, $count);
253
254
        $this->getJob();
255
256
        $count = $jobManager->countLiveJobs();
257
        self::assertEquals(3, $count);
258
259
        $count = $jobManager->countLiveJobs('asdf');
260
        self::assertEquals(0, $count);
261
262
        $count = $jobManager->countLiveJobs('fibonacci');
263
        self::assertEquals(3, $count);
264
265
        $count = $jobManager->countLiveJobs('fibonacci', 'test');
266
        self::assertEquals(0, $count);
267
268
        $count = $jobManager->countLiveJobs('fibonacci', 'fibonacci');
269
        self::assertEquals(3, $count);
270
271
        while ($job = $jobManager->getJob()) {
272
            $jobManager->deleteJob($job);
273
        }
274
    }
275
276
    public function testArchiveAllJobs()
277
    {
278
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
279
        $jobManager = self::$jobManager;
280
281
        while ($job = $jobManager->getJob()) {
282
            $jobManager->deleteJob($job);
283
        }
284
285
        $this->getJob();
286
287
        $count = $jobManager->countLiveJobs();
288
        $archiveCount = $this->runCountQuery($jobManager->getJobArchiveClass());
289
        self::assertEquals(1, $count);
290
        $allCount = $this->runCountQuery($jobManager->getJobClass());
291
        $counter = 0;
292
        $countJobs = function ($count) use (&$counter) {
293
            $counter += $count;
294
        };
295
        $jobManager->archiveAllJobs(null, null, $countJobs);
296
        self::assertEquals(0, $jobManager->countLiveJobs());
297
        self::assertEquals($allCount - 1, $this->runCountQuery($jobManager->getJobClass()));
298
        self::assertEquals($archiveCount + 1, $this->runCountQuery($jobManager->getJobArchiveClass()));
299
        self::assertEquals(1, $counter);
300
301
        $this->getJob();
302
        $this->getJob();
303
304
        $count = $jobManager->countLiveJobs();
305
        self::assertEquals(2, $count);
306
        $archiveCount = $this->runCountQuery($jobManager->getJobArchiveClass());
307
        $counter = 0;
308
        $jobManager->archiveAllJobs('fibonacci', null, $countJobs);
309
        self::assertEquals(0, $jobManager->countLiveJobs());
310
        self::assertEquals(2, $counter);
311
        self::assertEquals($archiveCount + 2, $this->runCountQuery($jobManager->getJobArchiveClass()));
312
313
        $this->getJob();
314
        $this->getJob();
315
316
        $count = $jobManager->countLiveJobs();
317
        self::assertEquals(2, $count);
318
319
        $jobManager->archiveAllJobs('fibonacc', null, $countJobs);
320
        self::assertEquals(2, $jobManager->countLiveJobs());
321
322
        $jobManager->archiveAllJobs('fibonacci', 'fibo', $countJobs);
323
        self::assertEquals(2, $jobManager->countLiveJobs());
324
325
        $jobManager->archiveAllJobs('fibonacci', 'fibonacci', $countJobs);
326
        self::assertEquals(0, $jobManager->countLiveJobs());
327
328
        while ($job = $jobManager->getJob()) {
329
            $jobManager->deleteJob($job);
330
        }
331
    }
332
333
    abstract protected function runCountQuery($class);
334
335
    public function testResetExceptionJobs()
336
    {
337
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
338
        $jobManager = self::$jobManager;
339
340
        $id = $this->createExceptionJob();
341
        $archiveObjectName = $jobManager->getJobArchiveClass();
342
        $objectManager = $jobManager->getObjectManager();
343
        $archiveRepository = $objectManager->getRepository($archiveObjectName);
344
        $result = $archiveRepository->find($id);
345
        self::assertNotNull($result);
346
        self::assertEquals(BaseJob::STATUS_EXCEPTION, $result->getStatus());
347
        if ($objectManager instanceof EntityManager) {
348
            JobManagerTest::createObjectManager();
349
            $jobManager = new self::$jobManagerClass(self::$runManager, self::$jobTimingManager, self::$objectManager, self::$objectName, self::$archiveObjectName);
350
            $jobManager->getObjectManager()->clear();
351
            $objectManager = $jobManager->getObjectManager();
352
        }
353
354
        $count = $jobManager->resetExceptionJobs();
355
356
        self::assertEquals(1, $count);
357
        $repository = $jobManager->getRepository();
358
        $job = $repository->find($id);
359
360
        self::assertNotNull($job);
361
        self::assertEquals(BaseJob::STATUS_NEW, $job->getStatus());
362
        self::assertNull($job->getStartedAt());
363
        self::assertNull($job->getFinishedAt());
364
        self::assertNull($job->getElapsed());
365
        self::assertNull($job->getMessage());
366
367
        $objectManager->remove($job);
368
        $objectManager->flush();
369
370
        $id = $this->createExceptionJob();
371
        $archiveObjectName = $jobManager->getJobArchiveClass();
372
        $objectManager = $jobManager->getObjectManager();
373
        $archiveRepository = $objectManager->getRepository($archiveObjectName);
374
        $result = $archiveRepository->find($id);
375
        $result->setMaxRetries(10);
376
        $result->setRetries(10);
377
        $objectManager->persist($result);
378
        $objectManager->flush();
379
        $count = $jobManager->resetExceptionJobs();
380
        self::assertEquals(0, $count);
381
        $job = $repository->find($id);
382
        self::assertNull($job);
383
        $job = $archiveRepository->find($id);
384
        self::assertNotNull($job);
385
        $objectManager->remove($job);
386
        $objectManager->flush();
387
    }
388
389
    protected function createExceptionJob()
390
    {
391
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
392
        $jobManager = self::$jobManager;
393
394
        /** @var Job $job */
395
        $job = $this->getJob();
396
        $id = $job->getId();
397
        $jobManager->deleteJob($job);
398
399
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
400
        $archiveObjectName = $jobManager->getJobArchiveClass();
401
402
        $objectManager = $jobManager->getObjectManager();
403
404
        $archiveRepository = $objectManager->getRepository($archiveObjectName);
405
        $result = $archiveRepository->find($id);
406
        self::assertNotNull($result);
407
        self::assertEquals($id, $result->getId());
408
409
        $result->setStatus(BaseJob::STATUS_EXCEPTION);
410
        $result->setStartedAt(Util::getMicrotimeDateTime());
411
        $result->setFinishedAt(new \DateTime());
412
        $result->setElapsed(12345);
413
        $result->setMessage('soomething');
414
        $objectManager->persist($result);
415
        $objectManager->flush();
416
417
        return $id;
418
    }
419
420
    /**
421
     * @param bool $endRun
422
     * @param bool $setId
423
     *
424
     * @return mixed
425
     */
426
    public function createStalledJob($endRun, $setId)
427
    {
428
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
429
        $jobManager = self::$jobManager;
430
431
        $job = new self::$jobClass(self::$worker, false, null);
432
        $job->fibonacci(1);
433
        self::assertNotNull($job->getId(), 'Job id should be generated');
434
        $job->setStatus(BaseJob::STATUS_RUNNING);
435
        $time = time();
436
        $date = new \DateTime("@$time");
437
        $job->setStartedAt($date);
438
        $id = $job->getId();
439
        $job = $jobManager->getRepository()->find($id);
440
441
        self::assertNotNull($job);
442
443
        $runClass = self::$runManager->getRunClass();
444
445
        $objectManager = $jobManager->getObjectManager();
446
        $run = new $runClass();
447
        $run->setLastHeartbeatAt(new \DateTime());
448
        if ($setId) {
449
            $run->setCurrentJobId($job->getId());
450
        }
451
        $objectManager->persist($run);
452
        $objectManager->flush();
453
        $runId = $run->getId();
454
        self::assertNotNull($runId);
455
        $job->setRunId($runId);
456
        $objectManager->persist($job);
457
        $objectManager->flush();
458
        if ($endRun) {
459
            $objectManager->remove($run);
460
            $objectManager->flush();
461
        }
462
        $id = $job->getId();
463
        $job = $jobManager->getRepository()->find($id);
464
465
        self::assertNotNull($job);
466
467
        if ($endRun) {
468
            $archivedRun = $objectManager->getRepository(self::$runManager->getRunArchiveClass())->find($runId);
469
470
            $minusTime = $time - (DoctrineJobManager::STALLED_SECONDS + 1);
471
            $archivedRun->setEndedAt(new \DateTime("@$minusTime"));
472
473
            $objectManager->persist($archivedRun);
474
            $objectManager->flush();
475
        }
476
        $id = $job->getId();
477
478
        return $id;
479
    }
480
481
    public function testResetStalledJobs()
482
    {
483
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
484
        $jobManager = self::$jobManager;
485
        $id = $this->createStalledJob(true, false);
486
487
        $objectManager = $jobManager->getObjectManager();
488
        $count = $jobManager->resetStalledJobs();
489
        self::assertEquals(1, $count);
490
491
        $job = $jobManager->getRepository()->find($id);
492
493
        self::assertNotNull($job);
494
        self::assertEquals(BaseJob::STATUS_NEW, $job->getStatus());
495
        self::assertNull($job->getStartedAt());
496
        self::assertNull($job->getFinishedAt());
497
        self::assertNull($job->getElapsed());
498
        self::assertNull($job->getMessage());
499
        self::assertEquals(1, $job->getStalls());
500
501
        $objectManager->remove($job);
502
        $objectManager->flush();
503
504
        $jobManager = self::$jobManager;
505
        $id = $this->createStalledJob(true, true);
506
507
        $objectManager = $jobManager->getObjectManager();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
508
        $count = $jobManager->resetStalledJobs();
509
        self::assertEquals(1, $count);
510
511
        $job = $jobManager->getRepository()->find($id);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getRepository() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
512
513
        self::assertNotNull($job);
514
        $objectManager->remove($job);
515
        $objectManager->flush();
516
517
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
518
        $id = $this->createStalledJob(false, false);
519
520
        $objectManager = $jobManager->getObjectManager();
521
        $count = $jobManager->resetStalledJobs();
522
        self::assertEquals(1, $count);
523
524
        $job = $jobManager->getRepository()->find($id);
525
526
        self::assertNotNull($job);
527
        self::assertEquals(BaseJob::STATUS_NEW, $job->getStatus());
528
        self::assertNull($job->getStartedAt());
529
        self::assertNull($job->getFinishedAt());
530
        self::assertNull($job->getElapsed());
531
        self::assertNull($job->getMessage());
532
        self::assertEquals(1, $job->getStalls());
533
534
        $objectManager->remove($job);
535
        $objectManager->flush();
536
537
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
538
        $jobManager = self::$jobManager;
539
        $id = $this->createStalledJob(false, true);
540
541
        $job = $jobManager->getRepository()->find($id);
542
        $objectManager = $jobManager->getObjectManager();
543
        $count = $jobManager->resetStalledJobs();
544
        self::assertEquals(0, $count);
545
546
        $objectManager->remove($job);
547
        $objectManager->flush();
548
549
        $id = $this->createStalledJob(true, false);
550
        $job = $jobManager->getRepository()->find($id);
551
        $job->setMaxRetries(10);
552
        $job->setRetries(10);
553
        $objectManager->persist($job);
554
        $objectManager->flush();
555
556
        $count = $jobManager->resetStalledJobs();
557
        self::assertEquals(0, $count);
558
        $job = $jobManager->getRepository()->find($id);
559
        self::assertNull($job);
560
        $job = $objectManager->getRepository($jobManager->getJobArchiveClass())->find($id);
561
        self::assertNotNull($job);
562
        $objectManager->remove($job);
563
        $objectManager->flush();
564
565
        $id = $this->createStalledJob(true, false);
566
        $job = $jobManager->getRepository()->find($id);
567
        $job->setMaxStalls(10);
568
        $job->setStalls(10);
569
        $objectManager->persist($job);
570
        $objectManager->flush();
571
572
        $count = $jobManager->resetStalledJobs();
573
        self::assertEquals(0, $count);
574
        $job = $jobManager->getRepository()->find($id);
575
        self::assertNull($job);
576
        $job = $objectManager->getRepository($jobManager->getJobArchiveClass())->find($id);
577
        self::assertNotNull($job);
578
        $objectManager->remove($job);
579
        $objectManager->flush();
580
    }
581
582
    public function testpruneExceptionJobs()
583
    {
584
        $job = $this->getJob();
585
        $id = $job->getId();
586
587
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
588
        $jobManager = self::$jobManager;
589
        $jobManager->deleteJob($job);
590
        $archiveObjectName = $jobManager->getJobArchiveClass();
591
592
        $objectManager = $jobManager->getObjectManager();
593
594
        $archiveRepository = $objectManager->getRepository($archiveObjectName);
595
        $result = $archiveRepository->find($id);
596
        self::assertNotNull($result);
597
        self::assertEquals($id, $result->getId());
598
599
        $result->setStatus(BaseJob::STATUS_EXCEPTION);
600
        $result->setStartedAt(new \DateTime());
601
        $result->setFinishedAt(new \DateTime());
602
        $result->setElapsed(12345);
603
        $result->setMessage('soomething');
604
        $objectManager->persist($result);
605
        $objectManager->flush();
606
607
        $count = $jobManager->pruneExceptionJobs('asdf');
608
        self::assertEquals(0, $count);
609
        $count = $jobManager->pruneExceptionJobs(null, 'asdf');
610
        self::assertEquals(0, $count);
611
        $count = $jobManager->pruneExceptionJobs('fibonacci', 'asdf');
612
        self::assertEquals(0, $count);
613
        $count = $jobManager->pruneExceptionJobs('fibonacci', 'asdf');
614
        self::assertEquals(0, $count);
615
        $count = $jobManager->pruneExceptionJobs('fibonacci', 'fibonacci');
616
        self::assertEquals(1, $count);
617
        $repository = $jobManager->getRepository();
618
        $job = $repository->find($id);
619
        $objectManager->clear();
620
        self::assertNull($job);
621
        $archiveJob = $archiveRepository->find($id);
622
        self::assertNull($archiveJob);
623
624
        $job = $this->getJob();
625
        $id = $job->getId();
626
        $objectManager->remove($job);
627
        $objectManager->flush();
628
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
629
        $jobManager = self::$jobManager;
630
        $archiveObjectName = $jobManager->getJobArchiveClass();
631
632
        $objectManager = $jobManager->getObjectManager();
633
634
        $archiveRepository = $objectManager->getRepository($archiveObjectName);
635
        $result = $archiveRepository->find($id);
636
        self::assertNotNull($result);
637
        self::assertEquals($id, $result->getId());
638
639
        $result->setStatus(BaseJob::STATUS_EXCEPTION);
640
        $result->setStartedAt(new \DateTime());
641
        $result->setFinishedAt(new \DateTime());
642
        $result->setElapsed(12345);
643
        $result->setMessage('soomething');
644
        $objectManager->persist($result);
645
        $objectManager->flush();
646
647
        $job = $this->getJob();
648
        $id = $job->getId();
649
        $objectManager->remove($job);
650
        $objectManager->flush();
651
652
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
653
        $jobManager = self::$jobManager;
654
        $archiveObjectName = $jobManager->getJobArchiveClass();
655
        $objectManager = $jobManager->getObjectManager();
656
657
        $archiveRepository = $objectManager->getRepository($archiveObjectName);
658
        $result = $archiveRepository->find($id);
659
        self::assertNotNull($result);
660
        self::assertEquals($id, $result->getId());
661
662
        $result->setStatus(BaseJob::STATUS_EXCEPTION);
663
        $result->setStartedAt(new \DateTime());
664
        $result->setFinishedAt(new \DateTime());
665
        $result->setElapsed(12345);
666
        $result->setMessage('soomething');
667
        $objectManager->persist($result);
668
        $objectManager->flush();
669
        $count = $jobManager->pruneExceptionJobs();
670
        self::assertEquals(2, $count);
671
    }
672
673
    public function testPruneStalledJobs()
674
    {
675
        static::setUpBeforeClass();
676
677
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
678
        $jobManager = self::$jobManager;
679
680
        $job = new self::$jobClass(self::$worker, false, null);
681
        $job->fibonacci(1);
682
        self::assertNotNull($job->getId(), 'Job id should be generated');
683
        $job->setStatus(BaseJob::STATUS_RUNNING);
684
        $time = time();
685
        $date = new \DateTime("@$time");
686
        $job->setStartedAt($date);
687
        $id = $job->getId();
688
        $job = $jobManager->getRepository()->find($id);
689
690
        self::assertNotNull($job);
691
692
        $runClass = self::$runManager->getRunClass();
693
694
        $objectManager = $jobManager->getObjectManager();
695
        $run = new $runClass();
696
        $run->setLastHeartbeatAt(new \DateTime());
697
        $objectManager->persist($run);
698
        $objectManager->flush();
699
        $runId = $run->getId();
700
        self::assertNotNull($runId);
701
        $job->setRunId($runId);
702
        $objectManager->persist($job);
703
        $objectManager->flush();
704
        $objectManager->remove($run);
705
        $objectManager->flush();
706
        $id = $job->getId();
707
        $job = $jobManager->getRepository()->find($id);
708
709
        self::assertNotNull($job);
710
711
        $archivedRun = $objectManager->getRepository(self::$runManager->getRunArchiveClass())->find($runId);
712
713
        $minusTime = $time - (DoctrineJobManager::STALLED_SECONDS + 1);
714
        $archivedRun->setEndedAt(new \DateTime("@$minusTime"));
715
716
        $objectManager->persist($archivedRun);
717
        $objectManager->flush();
718
719
        $count = $jobManager->pruneStalledJobs('asdf');
720
        self::assertEquals(0, $count);
721
        $count = $jobManager->pruneStalledJobs(null, 'asdf');
722
        self::assertEquals(0, $count);
723
        $count = $jobManager->pruneStalledJobs('fibonacci', 'asdf');
724
        self::assertEquals(0, $count);
725
        $count = $jobManager->pruneStalledJobs('fibonacci', 'fibonacci');
726
        self::assertEquals(1, $count);
727
728
        $job = $jobManager->getRepository()->find($id);
729
730
        self::assertNull($job);
731
732
        $archivedJob = $jobManager->getObjectManager()->getRepository($jobManager->getJobArchiveClass())->find($id);
733
734
        self::assertNotNull($archivedJob);
735
        self::assertEquals(StallableJob::STATUS_STALLED, $archivedJob->getStatus());
736
        self::assertEquals(1, $archivedJob->getStalls());
737
        $objectManager->remove($archivedJob);
738
        $objectManager->flush();
739
740
        // multiple
741
742
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
743
        $jobManager = self::$jobManager;
744
745
        $job = new self::$jobClass(self::$worker, false, null);
746
        $job->fibonacci(1);
747
        self::assertNotNull($job->getId(), 'Job id should be generated');
748
        $job->setStatus(BaseJob::STATUS_RUNNING);
749
        $time = time();
750
        $date = new \DateTime("@$time");
751
        $job->setStartedAt($date);
752
        $id = $job->getId();
753
        $job = $jobManager->getRepository()->find($id);
754
755
        self::assertNotNull($job);
756
757
        $runClass = self::$runManager->getRunClass();
758
759
        $objectManager = $jobManager->getObjectManager();
760
        $run = new $runClass();
761
        $run->setLastHeartbeatAt(new \DateTime());
762
        $objectManager->persist($run);
763
        $objectManager->flush();
764
        $runId = $run->getId();
765
        self::assertNotNull($runId);
766
        $job->setRunId($runId);
767
        $objectManager->persist($job);
768
        $objectManager->flush();
769
        $objectManager->remove($run);
770
        $objectManager->flush();
771
        $id = $job->getId();
772
        $job = $jobManager->getRepository()->find($id);
773
774
        self::assertNotNull($job);
775
776
        $archivedRun = $objectManager->getRepository(self::$runManager->getRunArchiveClass())->find($runId);
777
778
        $minusTime = $time - (DoctrineJobManager::STALLED_SECONDS + 1);
779
        $archivedRun->setEndedAt(new \DateTime("@$minusTime"));
780
781
        $objectManager->persist($archivedRun);
782
        $objectManager->flush();
783
784
        $job = new self::$jobClass(self::$worker, false, null);
785
        $job->fibonacci(1);
786
        self::assertNotNull($job->getId(), 'Job id should be generated');
787
        $job->setStatus(BaseJob::STATUS_RUNNING);
788
        $time = time();
789
        $date = new \DateTime("@$time");
790
        $job->setStartedAt($date);
791
        $id = $job->getId();
792
        $job = $jobManager->getRepository()->find($id);
793
794
        self::assertNotNull($job);
795
796
        $runClass = self::$runManager->getRunClass();
797
798
        $objectManager = $jobManager->getObjectManager();
799
        $run = new $runClass();
800
        $run->setLastHeartbeatAt(new \DateTime());
801
        $objectManager->persist($run);
802
        $objectManager->flush();
803
        $runId = $run->getId();
804
        self::assertNotNull($runId);
805
        $job->setRunId($runId);
806
        $objectManager->persist($job);
807
        $objectManager->flush();
808
        $objectManager->remove($run);
809
        $objectManager->flush();
810
        $id = $job->getId();
811
        $job = $jobManager->getRepository()->find($id);
812
813
        self::assertNotNull($job);
814
815
        $archivedRun = $objectManager->getRepository(self::$runManager->getRunArchiveClass())->find($runId);
816
817
        $minusTime = $time - (DoctrineJobManager::STALLED_SECONDS + 1);
818
        $archivedRun->setEndedAt(new \DateTime("@$minusTime"));
819
820
        $objectManager->persist($archivedRun);
821
        $objectManager->flush();
822
        $count = $jobManager->pruneStalledJobs();
823
        self::assertEquals(2, $count);
824
    }
825
826
    public function testBatchJobs()
827
    {
828
        $jobs = self::$jobManager->getRepository()->findAll();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getRepository() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
829
        foreach ($jobs as $job) {
830
            self::$jobManager->getObjectManager()->remove($job);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
831
        }
832
        self::$jobManager->getObjectManager()->flush();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
833
        self::$jobManager->getObjectManager()->clear();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
834
835
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
836
        $worker = self::$worker;
837
        $job1 = $worker->later()->fibonacci(1);
838
        $job2 = $worker->batchLater()->fibonacci(1);
839
        self::assertEquals($job1, $job2);
840
841
        $jobs = self::$jobManager->getRepository()->findAll();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getRepository() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
842
        self::assertCount(1, $jobs);
843
        self::assertEquals($job1, $jobs[0]);
844
        self::assertNull($jobs[0]->getPriority());
845
        self::$jobManager->getObjectManager()->remove($jobs[0]);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
846
        self::$jobManager->getObjectManager()->flush();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
847
        self::$jobManager->getObjectManager()->clear();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
848
849
        $job1 = $worker->later()->fibonacci(1);
850
        self::assertNull($job1->getPriority());
851
        $job2 = $worker->batchLater()->setPriority(3)->fibonacci(1);
852
        self::assertEquals($job1, $job2);
853
        self::assertNotNull($job2->getPriority());
854
855
        $jobs = self::$jobManager->getRepository()->findAll();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getRepository() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
856
        self::assertCount(1, $jobs);
857
        self::assertEquals($job1, $jobs[0]);
858
        self::assertNotNull($jobs[0]->getPriority());
859
860
        // Not
861
        $jobs = self::$jobManager->getRepository()->findAll();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getRepository() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
862
        foreach ($jobs as $job) {
863
            self::$jobManager->getObjectManager()->remove($job);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
864
        }
865
        self::$jobManager->getObjectManager()->remove($jobs[0]);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
866
        self::$jobManager->getObjectManager()->flush();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
867
        self::$jobManager->getObjectManager()->clear();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
868
869
        $job1 = $worker->later(100)->fibonacci(1);
870
871
        $time1 = new \DateTime();
872
        $job2 = $worker->batchLater(0)->fibonacci(1);
873
        $time2 = Util::getDateTimeFromDecimalFormat(Util::getMicrotimeDecimal());
874
875
        self::assertEquals($job1, $job2);
876
        self::assertGreaterThanOrEqual($time1, $job2->getWhenAt());
877
        self::assertLessThanOrEqual($time2, $job2->getWhenAt());
878
879
        $jobs = self::$jobManager->getRepository()->findAll();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getRepository() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
880
        self::assertCount(1, $jobs);
881
        self::assertEquals($job1, $jobs[0]);
882
        self::assertGreaterThanOrEqual($time1, $jobs[0]->getWhenAt());
883
        self::assertLessThanOrEqual($time2, $jobs[0]->getWhenAt());
884
        self::$jobManager->getObjectManager()->remove($jobs[0]);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
885
        self::$jobManager->getObjectManager()->flush();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
886
        self::$jobManager->getObjectManager()->clear();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
887
888
        $job1 = $worker->later(100)->setPriority(3)->fibonacci(1);
889
        $priority1 = $job1->getPriority();
890
        $time1 = Util::getDateTimeFromDecimalFormat(Util::getMicrotimeDecimal());
891
        $job2 = $worker->batchLater(0)->setPriority(1)->fibonacci(1);
892
        $time2 = Util::getDateTimeFromDecimalFormat(Util::getMicrotimeDecimal());
893
        self::assertEquals($job1, $job2);
894
        self::assertNotEquals($priority1, $job2->getPriority());
895
896
        self::assertEquals($job1, $job2);
897
        self::assertGreaterThanOrEqual($time1, $job2->getWhenAt());
898
        self::assertLessThanOrEqual($time2, $job2->getWhenAt());
899
    }
900
901
    public function testPruneExpiredJobs()
902
    {
903
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
904
        $jobManager = self::$jobManager;
905
        $objectManager = $jobManager->getObjectManager();
906
907
        $job = new self::$jobClass(self::$worker, false, null);
908
        $job->fibonacci(1);
909
        self::assertNotNull($job->getId(), 'Job id should be generated');
910
        $time = time() - 1;
911
        $date = new \DateTime("@$time");
912
        $job->setExpiresAt($date);
913
        $objectManager->persist($job);
914
        $objectManager->flush();
915
916
        $count = $jobManager->pruneExpiredJobs('asdf');
917
        self::assertEquals(0, $count);
918
        $count = $jobManager->pruneExpiredJobs(null, 'asdf');
919
        self::assertEquals(0, $count);
920
        $count = $jobManager->pruneExpiredJobs(null, 'fibonacci');
921
        self::assertEquals(1, $count);
922
923
        $job = new self::$jobClass(self::$worker, false, null);
924
        $job->fibonacci(1);
925
        self::assertNotNull($job->getId(), 'Job id should be generated');
926
        $time = time() - 1;
927
        $date = new \DateTime("@$time");
928
        $job->setExpiresAt($date);
929
        $objectManager->persist($job);
930
        $objectManager->flush();
931
932
        $job = new self::$jobClass(self::$worker, false, null);
933
        $job->fibonacci(1);
934
        self::assertNotNull($job->getId(), 'Job id should be generated');
935
        $time = time() - 1;
936
        $date = new \DateTime("@$time");
937
        $job->setExpiresAt($date);
938
        $objectManager->persist($job);
939
        $objectManager->flush();
940
941
        $count = $jobManager->pruneExpiredJobs(null, 'fibonacci');
942
        self::assertEquals(2, $count);
943
944
        $job = new self::$jobClass(self::$worker, false, null);
945
        $job->fibonacci(1);
946
        self::assertNotNull($job->getId(), 'Job id should be generated');
947
        $time = time() - 1;
948
        $date = new \DateTime("@$time");
949
        $job->setExpiresAt($date);
950
        $objectManager->persist($job);
951
        $objectManager->flush();
952
953
        $job = new self::$jobClass(self::$worker, false, null);
954
        $job->fibonacci(1);
955
        self::assertNotNull($job->getId(), 'Job id should be generated');
956
        $time = time() - 1;
957
        $date = new \DateTime("@$time");
958
        $job->setExpiresAt($date);
959
        $objectManager->persist($job);
960
        $objectManager->flush();
961
962
        $count = $jobManager->pruneExpiredJobs('fibonacci', 'fibonacci');
963
        self::assertEquals(2, $count);
964
965
        $job = new self::$jobClass(self::$worker, false, null);
966
        $job->fibonacci(1);
967
        self::assertNotNull($job->getId(), 'Job id should be generated');
968
        $time = time() - 1;
969
        $date = new \DateTime("@$time");
970
        $job->setExpiresAt($date);
971
        $objectManager->persist($job);
972
        $objectManager->flush();
973
974
        $job = new self::$jobClass(self::$worker, false, null);
975
        $job->fibonacci(1);
976
        self::assertNotNull($job->getId(), 'Job id should be generated');
977
        $time = time() - 1;
978
        $date = new \DateTime("@$time");
979
        $job->setExpiresAt($date);
980
        $objectManager->persist($job);
981
        $objectManager->flush();
982
983
        $count = $jobManager->pruneExpiredJobs('fibonacci');
984
        self::assertEquals(2, $count);
985
986
        $job = new self::$jobClass(self::$worker, false, null);
987
        $job->fibonacci(1);
988
        self::assertNotNull($job->getId(), 'Job id should be generated');
989
        $time = time() - 1;
990
        $date = new \DateTime("@$time");
991
        $job->setExpiresAt($date);
992
        $objectManager->persist($job);
993
        $objectManager->flush();
994
995
        $jobId1 = $job->getId();
996
997
        $job = new self::$jobClass(self::$worker, false, null);
998
        $job->fibonacci(1);
999
        self::assertNotNull($job->getId(), 'Job id should be generated');
1000
        $time = time() - 1;
1001
        $date = new \DateTime("@$time");
1002
        $job->setExpiresAt($date);
1003
        $objectManager->persist($job);
1004
        $objectManager->flush();
1005
1006
        $jobId2 = $job->getId();
1007
1008
        $count = $jobManager->pruneExpiredJobs();
1009
        self::assertEquals(2, $count);
1010
1011
        $archiveRepository = $jobManager->getObjectManager()->getRepository($jobManager->getJobArchiveClass());
1012
1013
        $job = $archiveRepository->find($jobId1);
1014
        self::assertNotNull($job);
1015
        self::assertEquals(Job::STATUS_EXPIRED, $job->getStatus());
1016
1017
        $job = $archiveRepository->find($jobId2);
1018
        self::assertNotNull($job);
1019
        self::assertEquals(Job::STATUS_EXPIRED, $job->getStatus());
1020
    }
1021
1022
    public function testPruneArchivedJobs()
1023
    {
1024
        /** @var JobManager|\Dtc\QueueBundle\ORM\JobManager $jobManager */
1025
        $jobManager = self::$jobManager;
1026
        $objectManager = $jobManager->getObjectManager();
1027
        $jobArchiveClass = $jobManager->getJobArchiveClass();
1028
        $jobArchiveRepository = $objectManager->getRepository($jobArchiveClass);
1029
1030
        self::$objectManager->getEventManager()->removeEventListener('preUpdate', self::$dtcQueueListener);
1031
1032
        $job = new self::$jobClass(self::$worker, false, null);
1033
        $job->fibonacci(1);
1034
        $id = $job->getId();
1035
        $objectManager->remove($job);
1036
        $objectManager->flush();
1037
1038
        $jobArchive = $jobArchiveRepository->find($id);
1039
        self::assertNotNull($jobArchive);
1040
        $time = time() - 86401;
1041
        $jobArchive->setUpdatedAt(new \DateTime("@$time"));
1042
        $objectManager->persist($jobArchive);
1043
        $objectManager->flush();
1044
1045
        $older = $time + 1;
1046
        $count = $jobManager->pruneArchivedJobs(new \DateTime("@$time"));
1047
        self::assertEquals(0, $count);
1048
        $count = $jobManager->pruneArchivedJobs(new \DateTime("@$older"));
1049
        self::assertEquals(1, $count);
1050
1051
        $job = new self::$jobClass(self::$worker, false, null);
1052
        $job->fibonacci(1);
1053
        $id = $job->getId();
1054
        $objectManager->remove($job);
1055
        $objectManager->flush();
1056
1057
        $jobArchive = $jobArchiveRepository->find($id);
1058
        self::assertNotNull($jobArchive);
1059
        $time = time() - 86401;
1060
        $jobArchive->setUpdatedAt(new \DateTime("@$time"));
1061
        $objectManager->persist($jobArchive);
1062
        $objectManager->flush();
1063
1064
        $job = new self::$jobClass(self::$worker, false, null);
1065
        $job->fibonacci(1);
1066
        $id = $job->getId();
1067
        $objectManager->remove($job);
1068
        $objectManager->flush();
1069
1070
        $jobArchive = $jobArchiveRepository->find($id);
1071
        self::assertNotNull($jobArchive);
1072
        $jobArchive->setUpdatedAt(new \DateTime("@$time"));
1073
        $objectManager->persist($jobArchive);
1074
        $objectManager->flush();
1075
        $older = $time + 1;
1076
        $count = $jobManager->pruneArchivedJobs(new \DateTime("@$time"));
1077
        self::assertEquals(0, $count);
1078
        $count = $jobManager->pruneArchivedJobs(new \DateTime("@$older"));
1079
        self::assertEquals(2, $count);
1080
1081
        self::$objectManager->getEventManager()->addEventListener('preUpdate', self::$dtcQueueListener);
1082
    }
1083
1084
    public function testPerformance()
1085
    {
1086
        $jobs = self::$jobManager->getRepository()->findAll();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getRepository() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
1087
        foreach ($jobs as $job) {
1088
            self::$jobManager->getObjectManager()->remove($job);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
1089
        }
1090
        self::$jobManager->getObjectManager()->flush();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
1091
1092
        self::$jobManager->getObjectManager()->clear();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
1093
        parent::testPerformance();
1094
    }
1095
1096
    protected function getBaseStatus()
1097
    {
1098
        /** @var DoctrineJobManager $jobManager */
1099
        $jobManager = self::$jobManager;
1100
        $job = new self::$jobClass(self::$worker, false, null);
1101
        $job->fibonacci(1);
1102
        $status = $jobManager->getStatus();
1103
        self::assertArrayHasKey('fibonacci->fibonacci()', $status);
1104
        $fibonacciStatus = $status['fibonacci->fibonacci()'];
1105
1106
        self::assertArrayHasKey(BaseJob::STATUS_NEW, $fibonacciStatus);
1107
        self::assertArrayHasKey(BaseJob::STATUS_EXCEPTION, $fibonacciStatus);
1108
        self::assertArrayHasKey(BaseJob::STATUS_RUNNING, $fibonacciStatus);
1109
        self::assertArrayHasKey(BaseJob::STATUS_SUCCESS, $fibonacciStatus);
1110
        self::assertArrayHasKey(Job::STATUS_EXPIRED, $fibonacciStatus);
1111
        self::assertArrayHasKey(StallableJob::STATUS_MAX_STALLS, $fibonacciStatus);
1112
        self::assertArrayHasKey(RetryableJob::STATUS_MAX_EXCEPTIONS, $fibonacciStatus);
1113
        self::assertArrayHasKey(RetryableJob::STATUS_MAX_FAILURES, $fibonacciStatus);
1114
        self::assertArrayHasKey(RetryableJob::STATUS_MAX_RETRIES, $fibonacciStatus);
1115
1116
        return [$job, $status];
1117
    }
1118
1119
    public function testGetStatus()
1120
    {
1121
        list($job1, $status1) = $this->getBaseStatus();
1122
        list($job2, $status2) = $this->getBaseStatus();
1123
        $fibonacciStatus1 = $status1['fibonacci->fibonacci()'];
1124
        $fibonacciStatus2 = $status2['fibonacci->fibonacci()'];
1125
1126
        self::assertEquals($fibonacciStatus1[BaseJob::STATUS_NEW] + 1, $fibonacciStatus2[BaseJob::STATUS_NEW]);
1127
        $jobManager = self::$jobManager;
1128
        $objectManager = $jobManager->getObjectManager();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Dtc\QueueBundle\Manager\JobManagerInterface as the method getObjectManager() does only exist in the following implementations of said interface: Dtc\QueueBundle\Doctrine\DoctrineJobManager, Dtc\QueueBundle\ODM\JobManager, Dtc\QueueBundle\ORM\JobManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
1129
        $objectManager->remove($job1);
1130
        $objectManager->remove($job2);
1131
    }
1132
}
1133