Skip to content

Commit 05a9546

Browse files
committed
implemented changes as suggested in review (apart from using PSR caching interface)
1 parent b19e753 commit 05a9546

File tree

4 files changed

+85
-34
lines changed

4 files changed

+85
-34
lines changed

CHANGELOG.md

+32-5
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,56 @@ Release notes for the ArangoDB-PHP driver 3.3.x
22
===============================================
33

44
Starting from release 3.3.1, the PHP driver has support for automatic failover, for
5-
ArangoDB servers that are started in the "resilient single" or active/passive failover
6-
mode. This setup requires using ArangoDB 3.3.
5+
ArangoDB servers that are started in the active failover mode. This setup requires
6+
using ArangoDB 3.3.
77

88
In order to use automatic failover from the PHP driver, simply change the "endpoint"
99
attribute of the connection options from a simple endpoint string into an array of
1010
endpoint strings:
1111

1212
$connectionOptions = [
13-
ConnectionOptions::OPTION_ENDPOINT => [ 'tcp://localhost:8531', 'tcp://localhost:8532', 'tcp://localhost:8530' ], // endpoints to connect to
13+
ConnectionOptions::OPTION_ENDPOINT => [ 'tcp://localhost:8531', 'tcp://localhost:8532', 'tcp://localhost:8530' ],
1414
...
1515
];
1616
$connection = new Connection($connectionOptions);
1717

1818
instead of just
1919

2020
$connectionOptions = [
21-
ConnectionOptions::OPTION_ENDPOINT => 'tcp://localhost:8530', // endpoint to connect to
21+
ConnectionOptions::OPTION_ENDPOINT => 'tcp://localhost:8530',
2222
...
2323
];
2424
$connection = new Connection($connectionOptions);
2525

2626

27-
Release notes for the ArangoDB-PHP driver 3.2.0
27+
Additionally, retrieving the endpoint value of `ConnectionOptions` will now always
28+
return an array of endpoints. For the single-server case, the returned value will be
29+
an array with the specified endpoint. When active failover is used, the result will
30+
be an array with the specified endpoints or the endpoints found (added) at runtime.
31+
For example, in
32+
33+
$options = [ ConnectionOptions::OPTION_ENDPOINT => 'tcp://127.0.0.1:8529' ];
34+
$co = new ConnectionOptions($options);
35+
print_r($co[ConnectionOptions::OPTION_ENDPOINT]);
36+
37+
This will now print an array (`[ 'tcp://127.0.0.1:8529' ]`) and not just the string
38+
(`tcp://127.0.0.1:8529'). Client applications that retrieve the endpoint value via
39+
the `ConnectionOptions` object and expect it to be a string should be adjusted to
40+
pick the first value from the now-returned result array instead.
41+
42+
Using the port option for setting up `ConnectionOptions` and reading it back is now
43+
deprecated and will not be useful when using different endpoints with different port
44+
numbers.
45+
46+
For example, reading the `port` option here will provide just one of the specified
47+
ports, so it should be avoided:
48+
49+
$options = [ ConnectionOptions::OPTION_ENDPOINT => [ 'tcp://127.0.0.1:8529', 'tcp://127.0.0.1:8530' ] ];
50+
$co = new ConnectionOptions($options);
51+
print_r($co[ConnectionOptions::OPTION_PORT]);
52+
53+
54+
Release notes for the ArangoDB-PHP driver 3.2.x
2855
===============================================
2956

3057
- the default value for the authentication type of the `Connection` class is now `Basic`

lib/ArangoDBClient/Connection.php

+8-8
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ public function getOption($name)
206206
*/
207207
public function get($url, array $customHeaders = [])
208208
{
209-
return $this->handleFailover(function() use (&$url, &$customHeaders) {
209+
return $this->handleFailover(function() use ($url, $customHeaders) {
210210
$response = $this->executeRequest(HttpHelper::METHOD_GET, $url, '', $customHeaders);
211211

212212
return $this->parseResponse($response);
@@ -226,7 +226,7 @@ public function get($url, array $customHeaders = [])
226226
*/
227227
public function post($url, $data, array $customHeaders = [])
228228
{
229-
return $this->handleFailover(function() use (&$url, &$data, &$customHeaders) {
229+
return $this->handleFailover(function() use ($url, $data, $customHeaders) {
230230
$response = $this->executeRequest(HttpHelper::METHOD_POST, $url, $data, $customHeaders);
231231

232232
return $this->parseResponse($response);
@@ -246,7 +246,7 @@ public function post($url, $data, array $customHeaders = [])
246246
*/
247247
public function put($url, $data, array $customHeaders = [])
248248
{
249-
return $this->handleFailover(function() use (&$url, &$data, &$customHeaders) {
249+
return $this->handleFailover(function() use ($url, $data, $customHeaders) {
250250
$response = $this->executeRequest(HttpHelper::METHOD_PUT, $url, $data, $customHeaders);
251251

252252
return $this->parseResponse($response);
@@ -265,7 +265,7 @@ public function put($url, $data, array $customHeaders = [])
265265
*/
266266
public function head($url, array $customHeaders = [])
267267
{
268-
return $this->handleFailover(function() use (&$url, &$customHeaders) {
268+
return $this->handleFailover(function() use ($url, $customHeaders) {
269269
$response = $this->executeRequest(HttpHelper::METHOD_HEAD, $url, '', $customHeaders);
270270

271271
return $this->parseResponse($response);
@@ -285,7 +285,7 @@ public function head($url, array $customHeaders = [])
285285
*/
286286
public function patch($url, $data, array $customHeaders = [])
287287
{
288-
return $this->handleFailover(function() use (&$url, &$data, &$customHeaders) {
288+
return $this->handleFailover(function() use ($url, $data, $customHeaders) {
289289
$response = $this->executeRequest(HttpHelper::METHOD_PATCH, $url, $data, $customHeaders);
290290

291291
return $this->parseResponse($response);
@@ -305,7 +305,7 @@ public function patch($url, $data, array $customHeaders = [])
305305
*/
306306
public function delete($url, array $customHeaders = [], $data = '')
307307
{
308-
return $this->handleFailover(function() use (&$url, &$customHeaders, $data) {
308+
return $this->handleFailover(function() use ($url, $customHeaders, $data) {
309309
$response = $this->executeRequest(HttpHelper::METHOD_DELETE, $url, $data, $customHeaders);
310310

311311
return $this->parseResponse($response);
@@ -455,7 +455,7 @@ private function closeHandle()
455455
if ($this->_handle && is_resource($this->_handle)) {
456456
@fclose($this->_handle);
457457
}
458-
$this->_handle = 0;
458+
$this->_handle = null;
459459
}
460460

461461
/**
@@ -528,7 +528,7 @@ private function executeRequest($method, $url, $data, array $customHeaders = [])
528528
// open the socket. note: this might throw if the connection cannot be established
529529
$handle = $this->getHandle();
530530

531-
if ($handle) {
531+
if ($handle !== null) {
532532
// send data and get response back
533533

534534
if ($traceFunc) {

lib/ArangoDBClient/ConnectionOptions.php

+22-18
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,12 @@ class ConnectionOptions implements \ArrayAccess
244244
public function __construct(array $options)
245245
{
246246
$this->_values = array_merge(self::getDefaults(), $options);
247+
248+
if (isset($this->_values[self::OPTION_ENDPOINT]) &&
249+
!is_array($this->_values[self::OPTION_ENDPOINT])) {
250+
$this->_values[self::OPTION_ENDPOINT] = [ $this->_values[self::OPTION_ENDPOINT] ];
251+
}
252+
247253
$this->loadOptionsFromCache();
248254
$this->validate();
249255
}
@@ -326,9 +332,7 @@ public function offsetGet($offset)
326332
*/
327333
public function getCurrentEndpoint()
328334
{
329-
if (!is_array($this->_values[self::OPTION_ENDPOINT])) {
330-
return $this->_values[self::OPTION_ENDPOINT];
331-
}
335+
assert(is_array($this->_values[self::OPTION_ENDPOINT]));
332336
return $this->_values[self::OPTION_ENDPOINT][$this->_currentEndpointIndex];
333337
}
334338

@@ -339,7 +343,8 @@ public function getCurrentEndpoint()
339343
*/
340344
public function haveMultipleEndpoints()
341345
{
342-
return is_array($this->_values[self::OPTION_ENDPOINT]) && (count($this->_values[self::OPTION_ENDPOINT]) > 1);
346+
assert(is_array($this->_values[self::OPTION_ENDPOINT]));
347+
return count($this->_values[self::OPTION_ENDPOINT]) > 1;
343348
}
344349

345350
/**
@@ -357,11 +362,7 @@ public function addEndpoint($endpoint)
357362
throw new ClientException(sprintf("invalid endpoint specification '%s'", $endpoint));
358363
}
359364

360-
// can only add an endpoint here if the list of endpoints is already an array
361-
if (!is_array($this->_values[self::OPTION_ENDPOINT])) {
362-
// make it an array now
363-
$this->_values[self::OPTION_ENDPOINT] = [ $this->_values[self::OPTION_ENDPOINT] ];
364-
}
365+
assert(is_array($this->_values[self::OPTION_ENDPOINT]));
365366
$found = array_search($endpoint, $this->_values[self::OPTION_ENDPOINT]);
366367
if ($found === false) {
367368
// a new endpoint we have not seen before
@@ -383,10 +384,8 @@ public function addEndpoint($endpoint)
383384
*/
384385
public function nextEndpoint()
385386
{
387+
assert(is_array($this->_values[self::OPTION_ENDPOINT]));
386388
$endpoints = $this->_values[self::OPTION_ENDPOINT];
387-
if (!is_array($endpoints)) {
388-
return $endpoints;
389-
}
390389

391390
$numberOfEndpoints = count($endpoints);
392391

@@ -412,7 +411,7 @@ public function nextEndpoint()
412411
private static function getDefaults()
413412
{
414413
return [
415-
self::OPTION_ENDPOINT => null,
414+
self::OPTION_ENDPOINT => [ ],
416415
self::OPTION_HOST => null,
417416
self::OPTION_PORT => DefaultValues::DEFAULT_PORT,
418417
self::OPTION_FAILOVER_TRIES => DefaultValues::DEFAULT_FAILOVER_TRIES,
@@ -494,6 +493,13 @@ private function validate()
494493
$this->_values[self::OPTION_ENDPOINT] = [ 'tcp://' . $this->_values[self::OPTION_HOST] . ':' . $this->_values[self::OPTION_PORT] ];
495494
unset($this->_values[self::OPTION_HOST]);
496495
}
496+
497+
if (!is_array($this->_values[self::OPTION_ENDPOINT])) {
498+
// make sure that we always have an array of endpoints
499+
$this->_values[self::OPTION_ENDPOINT] = [ $this->_values[self::OPTION_ENDPOINT] ];
500+
}
501+
502+
assert(is_array($this->_values[self::OPTION_ENDPOINT]));
497503

498504
// validate endpoint
499505
$ep = $this->getCurrentEndpoint();
@@ -516,11 +522,6 @@ private function validate()
516522
}
517523
}
518524

519-
if (is_array($this->_values[self::OPTION_ENDPOINT])) {
520-
// the number of endpoints we have determines the number of failover attempts we'll try
521-
$this->_values[self::OPTION_FAILOVER_TRIES] = count($this->_values[self::OPTION_ENDPOINT]);
522-
}
523-
524525
if (isset($this->_values[self::OPTION_AUTH_TYPE]) && !in_array(
525526
$this->_values[self::OPTION_AUTH_TYPE],
526527
self::getSupportedAuthTypes(), true
@@ -565,6 +566,9 @@ private function loadOptionsFromCache()
565566
$endpoints = $cache->get($this->_values[self::OPTION_MEMCACHED_ENDPOINTS_KEY]);
566567
if ($endpoints) {
567568
$this->_values[self::OPTION_ENDPOINT] = $endpoints;
569+
if (!is_array($this->_values[self::OPTION_ENDPOINT])) {
570+
$this->_values[self::OPTION_ENDPOINT] = [ $this->_values[self::OPTION_ENDPOINT] ];
571+
}
568572
}
569573
}
570574

tests/ConnectionTest.php

+23-3
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,38 @@ public function testEndpointAndPort()
6262
{
6363
$options = [ ConnectionOptions::OPTION_ENDPOINT => 'tcp://127.0.0.10:9242' ];
6464
$co = new ConnectionOptions($options);
65-
static::assertEquals('tcp://127.0.0.10:9242', $co[ConnectionOptions::OPTION_ENDPOINT]);
65+
static::assertEquals([ 'tcp://127.0.0.10:9242' ], $co[ConnectionOptions::OPTION_ENDPOINT]);
6666
static::assertEquals(9242, $co[ConnectionOptions::OPTION_PORT]);
6767

6868
$options = [ ConnectionOptions::OPTION_ENDPOINT => 'tcp://192.168.9.9:433' ];
6969
$co = new ConnectionOptions($options);
70-
static::assertEquals('tcp://192.168.9.9:433', $co[ConnectionOptions::OPTION_ENDPOINT]);
70+
static::assertEquals([ 'tcp://192.168.9.9:433' ], $co[ConnectionOptions::OPTION_ENDPOINT]);
7171
static::assertEquals(433, $co[ConnectionOptions::OPTION_PORT]);
7272

7373
$options = [ ConnectionOptions::OPTION_ENDPOINT => 'tcp://myserver.example.com:432' ];
7474
$co = new ConnectionOptions($options);
75-
static::assertEquals('tcp://myserver.example.com:432', $co[ConnectionOptions::OPTION_ENDPOINT]);
75+
static::assertEquals([ 'tcp://myserver.example.com:432' ], $co[ConnectionOptions::OPTION_ENDPOINT]);
7676
static::assertEquals(432, $co[ConnectionOptions::OPTION_PORT]);
77+
78+
$options = [ ConnectionOptions::OPTION_ENDPOINT => [ 'tcp://master:8529' ] ];
79+
$co = new ConnectionOptions($options);
80+
static::assertEquals([ 'tcp://master:8529' ], $co[ConnectionOptions::OPTION_ENDPOINT]);
81+
static::assertEquals(8529, $co[ConnectionOptions::OPTION_PORT]);
82+
83+
$options = [ ConnectionOptions::OPTION_ENDPOINT => [ 'tcp://master:1234' ] ];
84+
$co = new ConnectionOptions($options);
85+
static::assertEquals([ 'tcp://master:1234' ], $co[ConnectionOptions::OPTION_ENDPOINT]);
86+
static::assertEquals(1234, $co[ConnectionOptions::OPTION_PORT]);
87+
88+
$options = [ ConnectionOptions::OPTION_ENDPOINT => [ 'tcp://master:8529', 'tcp://slave:1235' ] ];
89+
$co = new ConnectionOptions($options);
90+
static::assertEquals([ 'tcp://master:8529', 'tcp://slave:1235' ], $co[ConnectionOptions::OPTION_ENDPOINT]);
91+
static::assertEquals(8529, $co[ConnectionOptions::OPTION_PORT]);
92+
93+
$options = [ ConnectionOptions::OPTION_ENDPOINT => [ 'tcp://master:8529', 'tcp://slave:8529', 'tcp://blackhole:8529' ] ];
94+
$co = new ConnectionOptions($options);
95+
static::assertEquals([ 'tcp://master:8529', 'tcp://slave:8529', 'tcp://blackhole:8529' ], $co[ConnectionOptions::OPTION_ENDPOINT]);
96+
static::assertEquals(8529, $co[ConnectionOptions::OPTION_PORT]);
7797

7898
$excepted = false;
7999
try {

0 commit comments

Comments
 (0)