Consumer::connect()   A
last analyzed

Complexity

Conditions 3
Paths 1

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 52
ccs 0
cts 29
cp 0
rs 9.0472
c 0
b 0
f 0
cc 3
nc 1
nop 2
crap 12

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
 * Consumer.php
4
 *
5
 * @copyright      More in license.md
6
 * @license        http://www.ipublikuj.eu
7
 * @author         Adam Kadlec http://www.ipublikuj.eu
8
 * @package        iPublikuj:WebSocketsZMQ!
9
 * @subpackage     Consumer
10
 * @since          1.0.0
11
 *
12
 * @date           28.02.17
13
 */
14
15
declare(strict_types = 1);
16
17
namespace IPub\WebSocketsZMQ\Consumer;
18
19
use Closure;
20
use ZMQ;
21
use ZMQSocketException;
22
use Throwable;
23
24
use Psr\Log;
25
26
use React;
27
use React\EventLoop;
28
use React\ZMQ as ReactZMQ;
29
30
use IPub;
31
use IPub\WebSocketsZMQ;
32
33
use IPub\WebSocketsWAMP\Application;
34
use IPub\WebSocketsWAMP\Entities;
35
use IPub\WebSocketsWAMP\PushMessages;
36
use IPub\WebSocketsWAMP\Serializers;
37
38
use IPub\WebSockets\Exceptions as WebSocketsExceptions;
39
40
/**
41
 * ZeroMQ consumer
42
 *
43
 * @package        iPublikuj:WebSocketsZMQ!
44
 * @subpackage     Consumer
45
 *
46
 * @author         Adam Kadlec <[email protected]>
47
 *
48 1
 * @method onSuccess(Consumer $consumer, $data = NULL)
49
 * @method onFail(Consumer $consumer, $data = NULL)
50
 */
51
final class Consumer extends PushMessages\Consumer
52
{
53
	/**
54
	 * @var Closure
55
	 */
56
	public $onSuccess = [];
57
58
	/**
59
	 * @var Closure
60
	 */
61
	public $onFail = [];
62
63
	/**
64
	 * @var WebSocketsZMQ\Configuration
65
	 */
66
	private $configuration;
67
68
	/**
69
	 * @var  Serializers\PushMessageSerializer
70
	 */
71
	private $serializer;
72
73
	/**
74
	 * @var ReactZMQ\SocketWrapper
75
	 */
76
	private $socket;
77
78
	/**
79
	 * @var  Log\LoggerInterface
80
	 */
81
	private $logger;
82
83
	/**
84
	 * @param WebSocketsZMQ\Configuration $configuration
85
	 * @param Serializers\PushMessageSerializer $serializer
86
	 * @param Log\LoggerInterface|NULL $logger
87
	 */
88 View Code Duplication
	public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
89
		WebSocketsZMQ\Configuration $configuration,
90 1
		Serializers\PushMessageSerializer $serializer,
91
		Log\LoggerInterface $logger = NULL
92 1
	) {
93 1
		parent::__construct('zmq');
94 1
95 1
		$this->configuration = $configuration;
96
		$this->serializer = $serializer;
97
		$this->logger = $logger === NULL ? new Log\NullLogger : $logger;
0 ignored issues
show
Documentation Bug introduced by
It seems like $logger === NULL ? new \...\NullLogger() : $logger can also be of type object<Psr\Log\NullLogger>. However, the property $logger is declared as type object<Psr\Log\LoggerInterface>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
98
	}
99
100
	/**
101
	 * {@inheritdoc}
102
	 *
103
	 * @throws ZMQSocketException
104
	 */
105
	public function connect(EventLoop\LoopInterface $loop, Application\IApplication $application)
106
	{
107
		$context = new ReactZMQ\Context($loop);
108
109
		$this->socket = $context->getSocket(ZMQ::SOCKET_PULL);
110
111
		$this->logger->info(sprintf(
112
			'ZMQ transport listening on %s:%s',
113
			$this->configuration->getHost(),
114
			$this->configuration->getPort()
115
		));
116
117
		$this->socket->bind($this->configuration->getProtocol() . '://' . $this->configuration->getHost() . ':' . $this->configuration->getPort());
118
119
		$this->socket->on('message', function ($data) use ($application) {
120
			try {
121
				/** @var Entities\PushMessages\IMessage $message */
122
				$message = $this->serializer->deserialize($data);
123
124
				$application->handlePush($message, $this->getName());
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
125
126
				$this->onSuccess($this, $data);
127
128
			} catch (WebSocketsExceptions\TerminateException $ex) {
0 ignored issues
show
Bug introduced by
The class IPub\WebSockets\Exceptions\TerminateException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
129
				throw $ex;
130
131
			} catch (Throwable $ex) {
132
				$this->logger->error(
133
					'ZMQ socket failed to ack message', [
134
						'exception_message' => $ex->getMessage(),
135
						'file'              => $ex->getFile(),
136
						'line'              => $ex->getLine(),
137
						'message'           => $data,
138
					]
139
				);
140
141
				$this->onFail($this, $data);
142
			}
143
		});
144
145
		$this->socket->on('error', function (Throwable $ex) use ($application) {
146
			$this->logger->error(
147
				'ZMQ socket failed to receive message', [
148
					'exception_message' => $ex->getMessage(),
149
					'file'              => $ex->getFile(),
150
					'line'              => $ex->getLine(),
151
				]
152
			);
153
154
			$this->onFail($this);
155
		});
156
	}
157
158
	/**
159
	 * {@inheritdoc}
160
	 */
161 1
	public function close() : void
162
	{
163
		$this->socket ?: $this->socket->close();
164
	}
165
}
166