Daemon::run()   D
last analyzed

Complexity

Conditions 9
Paths 18

Size

Total Lines 44
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 9

Importance

Changes 3
Bugs 1 Features 1
Metric Value
c 3
b 1
f 1
dl 0
loc 44
ccs 30
cts 30
cp 1
rs 4.909
cc 9
eloc 30
nc 18
nop 0
crap 9
1
<?php
2
3
namespace Equip\BeanstalkdConsumer;
4
5
use Aura\Cli\Stdio;
6
use Aura\Cli\Context;
7
use Aura\Cli\Status;
8
use Relay\ResolverInterface;
9
use Pheanstalk\Pheanstalk;
10
11
class Daemon
12
{
13
    /**
14
     * @var ResolverInterface
15
     */
16
    private $resolver;
17
18
    /**
19
     * @var Stdio
20
     */
21
    private $stdio;
22
23
    /**
24
     * @var Context
25
     */
26
    private $context;
27
28
    /**
29
     * @var Pheanstalk
30
     */
31
    private $pheanstalk;
32
33
    /**
34
     * @var callable
35
     */
36
    private $listener;
37
38
    /**
39
     * @param ResolverInterface $resolver
40
     * @param Stdio $stdio
41
     * @param Context $context
42
     * @param Pheanstalk $pheanstalk
43
     */
44 8
    public function __construct(
45
        ResolverInterface $resolver,
46
        Stdio $stdio,
47
        Context $context,
48
        Pheanstalk $pheanstalk
49
    ) {
50 8
        $this->resolver = $resolver;
51 8
        $this->stdio = $stdio;
52 8
        $this->context = $context;
53 8
        $this->pheanstalk = $pheanstalk;
54
        $this->listener = function () { return true; };
0 ignored issues
show
Coding Style introduced by
It is generally recommended to place each PHP statement on a line by itself.

Let’s take a look at an example:

// Bad
$a = 5; $b = 6; $c = 7;

// Good
$a = 5;
$b = 6;
$c = 7;
Loading history...
55 8
    }
56
57
    /**
58
     * @param callable $listener
59
     */
60 8
    public function setListener(callable $listener)
61
    {
62 8
        $this->listener = $listener;
63 8
    }
64
65
    /**
66
     * @return int Status code to exit with
67
     */
68 8
    public function run()
69
    {
70 8
        $env = $this->context->env;
71 8
        $tube = $env->get('BEANSTALKD_TUBE') ?: 'default';
72 8
        $class = $env->get('BEANSTALKD_CONSUMER');
73 8
        if (!$class) {
74 1
            $this->stdio->outln('<<red>>BEANSTALKD_CONSUMER environmental variable is not set<<reset>>');
75 1
            return Status::USAGE;
76
        }
77 7
        if (!class_exists($class)) {
78 1
            $this->stdio->outln(sprintf('<<red>>BEANSTALKD_CONSUMER does not reference a locatable class: %s<<reset>>', $class));
79 1
            return Status::DATAERR;
80
        }
81 6
        if (!in_array(ConsumerInterface::class, class_implements($class))) {
82 1
            $this->stdio->outln(sprintf('<<red>>BEANSTALKD_CONSUMER references a class that does not implement ConsumerInterface: %s<<reset>>', $class));
83 1
            return Status::DATAERR;
84
        }
85
86 5
        $this->pheanstalk->watchOnly($tube);
87 5
        $consumer = call_user_func($this->resolver, $class);
88
89 5
        while (call_user_func($this->listener)) {
90 5
            $reserved = $this->pheanstalk->reserve();
91 5
            if (!$reserved) {
92 1
                continue;
93
            }
94 4
            $job = new Job($reserved->getId(), $reserved->getData());
95
96
            try {
97 4
                $result = $consumer->consume($job);
98 3
                if ($result === false) {
99 1
                    $this->pheanstalk->release($job);
100 1
                    continue;
101
                }
102 3
            } catch (\Exception $e) {
103 1
                $this->pheanstalk->release($job);
104 1
                throw $e;
105
            }
106
107 2
            $this->pheanstalk->delete($job);
108 2
        }
109
110 4
        return Status::SUCCESS;
111
    }
112
}
113