Skip to content

Commit 226d485

Browse files
committed
implemented and used timeout exception where relevant
1 parent b71dba7 commit 226d485

File tree

5 files changed

+48
-11
lines changed

5 files changed

+48
-11
lines changed

phpunit.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
</testsuites>
77
<php>
88
<var name="NEO_USER" value="neo4j"/>
9-
<var name="NEO_PASS" value="nothing"/>
9+
<var name="NEO_PASS" value="test"/>
1010
</php>
1111
<filter>
1212
<whitelist>

src/connection/Socket.php

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55
use Bolt\Bolt;
66
use Bolt\error\ConnectException;
7+
use Bolt\error\ConnectionTimeoutException;
8+
use function microtime;
9+
use function round;
10+
use function socket_get_status;
11+
use function socket_strerror;
712

813
/**
914
* Socket class
@@ -20,6 +25,10 @@ class Socket extends AConnection
2025
*/
2126
private $socket = false;
2227

28+
private const RESOURCE_UNAVAILABLE_CODE = 11;
29+
/** @var float|null */
30+
private $timetAtTimeoutConfiguration;
31+
2332
/**
2433
* Create socket connection
2534
* @return bool
@@ -73,8 +82,7 @@ public function write(string $buffer)
7382
while (0 < $size) {
7483
$sent = socket_write($this->socket, $buffer, $size);
7584
if ($sent === false) {
76-
$code = socket_last_error($this->socket);
77-
throw new ConnectException(socket_strerror($code), $code);
85+
$this->throwConnectException();
7886
}
7987

8088
$buffer = mb_strcut($buffer, $sent, null, '8bit');
@@ -99,8 +107,7 @@ public function read(int $length = 2048): string
99107
do {
100108
$readed = socket_read($this->socket, $length - mb_strlen($output, '8bit'), PHP_BINARY_READ);
101109
if ($readed === false) {
102-
$code = socket_last_error($this->socket);
103-
throw new ConnectException(socket_strerror($code), $code);
110+
$this->throwConnectException();
104111
}
105112
$output .= $readed;
106113
} while (mb_strlen($output, '8bit') < $length);
@@ -135,5 +142,23 @@ private function configureTimeout(): void
135142
$timeoutOption = ['sec' => $timeoutSeconds, 'usec' => $microSeconds];
136143
socket_set_option($this->socket, SOL_SOCKET, SO_RCVTIMEO, $timeoutOption);
137144
socket_set_option($this->socket, SOL_SOCKET, SO_SNDTIMEO, $timeoutOption);
145+
$this->timetAtTimeoutConfiguration = microtime(true);
146+
}
147+
148+
/**
149+
* @return mixed
150+
* @throws ConnectException
151+
* @throws ConnectionTimeoutException
152+
*/
153+
private function throwConnectException()
154+
{
155+
$code = socket_last_error($this->socket);
156+
if ($code === self::RESOURCE_UNAVAILABLE_CODE) {
157+
$timediff = microtime(true) - $this->timetAtTimeoutConfiguration;
158+
if ($timediff >= $this->timeout) {
159+
throw ConnectionTimeoutException::createFromTimeout($this->timeout);
160+
}
161+
}
162+
throw new ConnectException(socket_strerror($code), $code);
138163
}
139164
}

src/connection/StreamSocket.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
use Bolt\Bolt;
77
use Bolt\error\ConnectException;
8+
use Bolt\error\ConnectionTimeoutException;
89
use function floor;
910
use function stream_set_timeout;
1011

@@ -99,7 +100,7 @@ public function read(int $length = 2048): string
99100
$res = stream_get_contents($this->stream, $length);
100101

101102
if (stream_get_meta_data($this->stream)["timed_out"])
102-
throw new ConnectException('Connection timeout reached after '.$this->timeout.' seconds.');
103+
throw ConnectionTimeoutException::createFromTimeout($this->timeout);
103104

104105
if (empty($res))
105106
throw new ConnectException('Read error');
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Bolt\error;
4+
5+
class ConnectionTimeoutException extends ConnectException
6+
{
7+
public static function createFromTimeout(float $timeout): self
8+
{
9+
return new self('Connection timeout reached after '.$timeout.' seconds.');
10+
}
11+
}

tests/connection/AConnectionTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use Bolt\connection\IConnection;
77
use Bolt\connection\Socket;
88
use Bolt\connection\StreamSocket;
9-
use Bolt\error\ConnectException;
9+
use Bolt\error\ConnectionTimeoutException;
1010
use Bolt\error\MessageException;
1111
use Bolt\helpers\Auth;
1212
use Bolt\protocol\V4;
@@ -38,7 +38,7 @@ public function testMillisecondTimeout(string $alias): void
3838
$protocol->run('FOREACH ( i IN range(1,10000) |
3939
MERGE (d:Day {day: i})
4040
)');
41-
} catch (ConnectException $e) {
41+
} catch (ConnectionTimeoutException $e) {
4242
$newTime = microtime(true);
4343

4444
$this->assertEqualsWithDelta(1.5, $newTime - $time, 0.2);
@@ -62,7 +62,7 @@ public function testSecondsTimeout(string $alias): void
6262
MERGE (d:Day {day: i})
6363
)');
6464
$this->fail('No timeout error triggered');
65-
} catch (ConnectException $e) {
65+
} catch (ConnectionTimeoutException $e) {
6666
$newTime = microtime(true);
6767

6868
$this->assertEqualsWithDelta(1.0, $newTime - $time, 0.2);
@@ -86,7 +86,7 @@ public function testTimeoutRecoverAndReset(string $alias): void
8686
MERGE (d:Day {day: i})
8787
)');
8888
$this->fail('No timeout error triggered');
89-
} catch (ConnectException $e) {
89+
} catch (ConnectionTimeoutException $e) {
9090
$newTime = microtime(true);
9191

9292
$this->assertEqualsWithDelta(1.0, $newTime - $time, 0.2);
@@ -110,7 +110,7 @@ public function testTimeoutRecoverAndReset(string $alias): void
110110
MERGE (d:Day {day: i})
111111
)');
112112
$this->fail('No timeout error triggered');
113-
} catch (ConnectException $e) {
113+
} catch (ConnectionTimeoutException $e) {
114114
$newTime = microtime(true);
115115

116116
$this->assertEqualsWithDelta(1.0, $newTime - $time, 0.2);

0 commit comments

Comments
 (0)