Completed
Pull Request — master (#309)
by De Cramer
14:06
created

Factory::createConnection()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 25
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 2
Bugs 0 Features 1
Metric Value
dl 0
loc 25
ccs 0
cts 12
cp 0
rs 8.8571
c 2
b 0
f 1
cc 3
eloc 12
nc 3
nop 1
crap 12
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: olive
5
 * Date: 12/03/2017
6
 * Time: 15:57
7
 */
8
9
namespace eXpansion\Framework\Core\Services\DedicatedConnection;
10
11
use eXpansion\Framework\Core\Services\Console;
12
use Maniaplanet\DedicatedServer\Connection;
13
use Maniaplanet\DedicatedServer\Xmlrpc\TransportException;
14
use Psr\Log\LoggerInterface;
15
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
16
use Symfony\Component\EventDispatcher\GenericEvent;
17
18
/**
19
 * Service factory to create connection to the dedicated server.
20
 *
21
 * @package eXpansion\Framework\Core\Services\DedicatedConnection
22
 */
23
class Factory
24
{
25
    const EVENT_CONNECTED = 'expansion.dedicated.connected';
26
27
    /** @var Connection */
28
    protected $connection;
29
30
    /** @var string The name/ip of the host */
31
    protected $host;
32
33
    /** @var int */
34
    protected $port;
35
36
    /** @var int */
37
    protected $timeout;
38
39
    /** @var string */
40
    protected $user;
41
42
    /** @var string */
43
    protected $password;
44
45
    /** @var LoggerInterface */
46
    protected $logger;
47
48
    /** @var Console */
49
    protected $console;
50
51
    /** @var EventDispatcherInterface */
52
    protected $eventDispatcher;
53
54
    /**
55
     * Factory constructor.
56
     *
57
     * @param                          $host
58
     * @param                          $port
59
     * @param                          $timeout
60
     * @param                          $user
61
     * @param                          $password
62
     * @param LoggerInterface          $logger
63
     * @param Console                  $console
64
     * @param EventDispatcherInterface $eventDispatcher
65
     */
66 164
    public function __construct(
67
        $host,
68
        $port,
69
        $timeout,
70
        $user,
71
        $password,
72
        LoggerInterface $logger,
73
        Console $console,
74
        EventDispatcherInterface $eventDispatcher
75
    ) {
76 164
        $this->host = $host;
77 164
        $this->port = $port;
78 164
        $this->timeout = $timeout;
79 164
        $this->user = $user;
80 164
        $this->password = $password;
81 164
        $this->logger = $logger;
82 164
        $this->console = $console;
83 164
        $this->eventDispatcher = $eventDispatcher;
84 164
    }
85
86
    /**
87
     * Attempt to connect to the dedicated server.
88
     *
89
     * @param int $maxAttempts
90
     *
91
     * @return Connection
92
     * @throws TransportException when connection fails.
93
     */
94
    public function createConnection($maxAttempts = 3)
95
    {
96
97
        if (is_null($this->connection)) {
98
            $lastExcelption = $this->attemptConnection($maxAttempts);
99
100
            if (!is_null($lastExcelption)) {
101
                $this->console->getSfStyleOutput()->error(
102
                    [
103
                        "Looks like your Dedicated server is either offline or has wrong config settings",
104
                        "Error message: " . $lastExcelption->getMessage()
105
                    ]
106
                );
107
                $this->logger->error("Unable to open connection for Dedicated server", ["exception" => $lastExcelption]);
108
109
                throw $lastExcelption;
110
            }
111
112
            // Dispatch connected event.
113
            $event = new GenericEvent($this->connection);
114
            $this->eventDispatcher->dispatch(self::EVENT_CONNECTED, $event);
115
        }
116
117
        return $this->connection;
118
    }
119
120
    /**
121
     * @param $maxAttempts
122
     *
123
     * @return \Exception|TransportException|null
124
     */
125
    protected function attemptConnection($maxAttempts)
126
    {
127
        $attempts = 0;
128
        $lastExcelption = null;
129
130
        do {
131
132
            if (!is_null($lastExcelption)) {
133
                // Not first error.
134
                $lastExcelption = null;
135
136
                $this->console->getSfStyleOutput()->block(
137
                    "Will attempt to re-connect to dedicated server in 30seconds"
138
                );
139
                sleep(30);
140
            }
141
142
            try {
143
                $this->console->writeln('Attempting to connect to the dedicated server!');
144
145
                $this->connection = Connection::factory(
146
                    $this->host,
147
                    $this->port,
148
                    $this->timeout,
149
                    $this->user,
150
                    $this->password
151
                );
152
153
            } catch (\Exception $e) {
154
                $lastExcelption = $e;
155
                $attempts++;
156
                $remainingAttemps = $maxAttempts - $attempts;
157
158
                $this->console->getSfStyleOutput()->error(
159
                    [
160
                        "Cound't connect to the dedicated server !",
161
                        "Attempt : $attempts, Remaining attemps : $remainingAttemps ",
162
                        $e->getMessage(),
163
                    ]
164
                );
165
            }
166
        } while($attempts < $maxAttempts && !is_null($lastExcelption));
167
168
        return $lastExcelption;
169
    }
170
171
    /**
172
     * Get connection to the dedicated.
173
     *
174
     * @return Connection
175
     */
176
    public function getConnection()
177
    {
178
        return $this->connection;
179
    }
180
}
181