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

RpcServer::pushMessage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 17
rs 9.4285
cc 1
eloc 13
nc 1
nop 9

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
}