Completed
Push — master ( 4c9af5...c5590c )
by Daniel
03:25
created

RpcServer::getLogger()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Cmobi\RabbitmqBundle\Rpc;
4
5
use Cmobi\RabbitmqBundle\Rpc\Exception\InvalidRpcServerClassException;
6
use Cmobi\RabbitmqBundle\Rpc\Exception\NotFoundRpcServiceException;
7
use PhpAmqpLib\Channel\AMQPChannel;
8
use PhpAmqpLib\Connection\AMQPStreamConnection;
9
use PhpAmqpLib\Exception\AMQPRuntimeException;
10
use Psr\Log\LoggerInterface;
11
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
12
13
class RpcServer
14
{
15
    use ContainerAwareTrait;
16
17
    private $rpcServices;
18
    private $connection;
19
    private $logger;
20
    private $channel;
21
22
    public function __construct(array $rpcServices, AMQPStreamConnection $connection = null)
23
    {
24
        if (!$rpcServices) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $rpcServices of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

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

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

Loading history...
25
            throw new NotFoundRpcServiceException('no rpc services found.');
26
        }
27
        $this->rpcServices = $rpcServices;
28
29
        if (!is_null($connection)) {
30
            $this->connection = $connection;
31
        }
32
    }
33
34
    /**
35
     * @param $queue
36
     * @param RpcServiceInterface $serviceCallback
37
     * @param bool|false $passive
38
     * @param bool|false $durable
39
     * @param bool|false $exclusive
40
     * @param bool|true $auto_delete
41
     * @param bool|false $nowait
42
     * @param null $arguments
43
     * @param null $ticket
44
     */
45
    public function pushMessage(
46
        $queue,
47
        RpcServiceInterface $serviceCallback,
48
        $passive = false,
49
        $durable = false,
50
        $exclusive = false,
51
        $auto_delete = true,
52
        $nowait = false,
53
        $arguments = null,
54
        $ticket = null
55
    )
56
    {
57
        $this->getChannel()->queue_declare(
58
            $queue, $passive, $durable, $exclusive, $auto_delete, $nowait, $arguments, $ticket
59
        );
60
        $this->getChannel()->basic_consume($queue, '', false, false, $exclusive, $nowait, $serviceCallback->createCallback());
61
    }
62
63
    public function run()
64
    {
65
        foreach ($this->rpcServices as $serviceName) {
66
            $service = $this->getContainer()->get($serviceName);
67
68
            if (!$service instanceof RpcServiceInterface) {
69
                throw new InvalidRpcServerClassException(
70
                    'Failed start RpcServer: %s is not instance of RpcServiceInterface'. $serviceName
71
                );
72
            }
73
            list(
74
                $name, $passive, $durable, $exclusive, $auto_delete, $nowait, $arguments, $ticket
0 ignored issues
show
Unused Code introduced by
The assignment to $name is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
75
                ) = array_values($service->getQueueOptions());
76
            $this->pushMessage(
77
                $service->getQueueName(),
78
                $service,
79
                $passive,
80
                $durable,
81
                $exclusive,
82
                $auto_delete,
83
                $nowait,
84
                $arguments,
85
                $ticket
86
            );
87
        }
88
89
        while(count($this->getChannel()->callbacks)) {
90
            try {
91
                $this->getChannel()->wait();
92
            } catch (AMQPRuntimeException $e) {
93
94
                if ($this->logger instanceof LoggerInterface) {
95
                    $this->logger->error(
96
                        sprintf(
97
                            'Failed process queue with error: %s',
98
                            $e->getMessage()
99
                        )
100
                    );
101
                }
102
                continue;
103
            }
104
        }
105
106
        $this->getChannel()->close();
107
        $this->getConnection()->close();
108
    }
109
110
    /**
111
     * @throws \Cmobi\RabbitmqBundle\Amqp\Exception\NotFoundAMQPConnectionFactoryException
112
     */
113
    public function buildChannel()
114
    {
115
        if (!$this->connection instanceof AMQPStreamConnection) {
116
            $connectionManager = $this->getContainer()->get('cmobi_rabbitmq.connection.manager');
117
            $this->connection = $connectionManager->getConnection();
118
        }
119
        $this->channel = $this->connection->channel();
120
        $qos = 1;
121
122
        if ($this->getContainer()->hasParameter('cmobi_rabbitmq.basic_qos')) {
123
            $qos = $this->getContainer()->getParameter('cmobi_rabbitmq.basic_qos');
124
        }
125
        $this->getChannel()->basic_qos(null, $qos, null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
126
    }
127
128
    /**
129
     * @return AMQPStreamConnection
130
     */
131
    protected function getConnection()
132
    {
133
        return $this->connection;
134
    }
135
136
    /**
137
     * @return AMQPChannel
138
     */
139
    protected function getChannel()
140
    {
141
        return $this->channel;
142
    }
143
144
    /**
145
     * @return \Symfony\Component\DependencyInjection\ContainerInterface
146
     */
147
    protected function getContainer()
148
    {
149
        return $this->container;
150
    }
151
152
    /**
153
     * @return LoggerInterface
154
     */
155
    public function getLogger()
156
    {
157
        return $this->logger;
158
    }
159
160
    /**
161
     * @param LoggerInterface $logger
162
     */
163
    public function setLogger(LoggerInterface $logger)
164
    {
165
        $this->logger = $logger;
166
    }
167
}