-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added sharded client and client interface
- Loading branch information
Showing
7 changed files
with
284 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?php | ||
|
||
namespace Aternos\Etcd; | ||
|
||
use Aternos\Etcd\Exception\Status\InvalidResponseStatusCodeException; | ||
|
||
/** | ||
* Interface ClientInterface | ||
* | ||
* @package Aternos\Etcd | ||
*/ | ||
interface ClientInterface | ||
{ | ||
public function getHostname(): string; | ||
|
||
/** | ||
* Put a value into the key store | ||
* | ||
* @param string $key | ||
* @param mixed $value | ||
* @param bool $prevKv Get the previous key value in the response | ||
* @param int $lease | ||
* @param bool $ignoreLease Ignore the current lease | ||
* @param bool $ignoreValue Updates the key using its current value | ||
* @return string|null Returns previous value if $prevKv is set to true | ||
* @throws InvalidResponseStatusCodeException | ||
*/ | ||
public function put(string $key, $value, bool $prevKv = false, int $lease = 0, bool $ignoreLease = false, bool $ignoreValue = false); | ||
|
||
/** | ||
* Get a key value | ||
* | ||
* @param string $key | ||
* @return bool|string | ||
* @throws InvalidResponseStatusCodeException | ||
*/ | ||
public function get(string $key); | ||
|
||
/** | ||
* Delete a key | ||
* | ||
* @param string $key | ||
* @return bool | ||
* @throws InvalidResponseStatusCodeException | ||
*/ | ||
public function delete(string $key); | ||
|
||
/** | ||
* Put $value if $key value matches $previousValue otherwise $returnNewValueOnFail | ||
* | ||
* @param string $key | ||
* @param mixed $value The new value to set | ||
* @param mixed $previousValue The previous value to compare against | ||
* @param bool $returnNewValueOnFail | ||
* @return bool|string | ||
* @throws InvalidResponseStatusCodeException | ||
*/ | ||
public function putIf(string $key, $value, $previousValue, bool $returnNewValueOnFail = false); | ||
|
||
/** | ||
* Delete if $key value matches $previous value otherwise $returnNewValueOnFail | ||
* | ||
* @param string $key | ||
* @param $previousValue | ||
* @param bool $returnNewValueOnFail | ||
* @return bool|string | ||
* @throws InvalidResponseStatusCodeException | ||
*/ | ||
public function deleteIf(string $key, $previousValue, bool $returnNewValueOnFail = false); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
namespace Aternos\Etcd\Exception; | ||
|
||
/** | ||
* Class InvalidClientException | ||
* | ||
* @package Aternos\Etcd\Exception | ||
*/ | ||
class InvalidClientException extends \Exception | ||
{ | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
<?php | ||
|
||
namespace Aternos\Etcd; | ||
|
||
use Aternos\Etcd\Exception\InvalidClientException; | ||
use Flexihash\Flexihash; | ||
|
||
/** | ||
* Class ShardedClient | ||
* | ||
* @package Aternos\Etcd | ||
*/ | ||
class ShardedClient implements ClientInterface | ||
{ | ||
/** | ||
* @var ClientInterface[] | ||
*/ | ||
protected $clients = []; | ||
|
||
/** | ||
* @var ClientInterface[] | ||
*/ | ||
protected $keyCache = []; | ||
|
||
/** | ||
* @var Flexihash | ||
*/ | ||
protected $hash = null; | ||
|
||
/** | ||
* ShardedClient constructor. | ||
* | ||
* @param ClientInterface[] $clients | ||
* @throws InvalidClientException | ||
*/ | ||
public function __construct(array $clients) | ||
{ | ||
foreach ($clients as $client) { | ||
if (!$client instanceof ClientInterface) { | ||
throw new InvalidClientException("Invalid client in client list."); | ||
} | ||
|
||
$this->clients[$client->getHostname()] = $client; | ||
} | ||
} | ||
|
||
/** | ||
* Get the correct client object for that key through consistent hashing | ||
* | ||
* @param string $key | ||
* @return ClientInterface | ||
* @throws \Flexihash\Exception | ||
*/ | ||
protected function getClientFromKey(string $key): ClientInterface | ||
{ | ||
if (isset($this->keyCache[$key])) { | ||
return $this->keyCache[$key]; | ||
} | ||
|
||
if ($this->hash === null) { | ||
$this->hash = new Flexihash(); | ||
foreach ($this->clients as $client) { | ||
$this->hash->addTarget($client->getHostname()); | ||
} | ||
} | ||
|
||
$clientHostname = $this->hash->lookup($key); | ||
$this->keyCache[$key] = $this->clients[$clientHostname]; | ||
return $this->keyCache[$key]; | ||
} | ||
|
||
|
||
public function getHostname(): string | ||
{ | ||
return implode("-", array_keys($this->clients)); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
* @throws \Flexihash\Exception | ||
*/ | ||
public function put(string $key, $value, bool $prevKv = false, int $lease = 0, bool $ignoreLease = false, bool $ignoreValue = false) | ||
{ | ||
return $this->getClientFromKey($key)->put($key, $value, $prevKv, $lease, $ignoreLease, $ignoreValue); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
* @throws \Flexihash\Exception | ||
*/ | ||
public function get(string $key) | ||
{ | ||
return $this->getClientFromKey($key)->get($key); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
* @throws \Flexihash\Exception | ||
*/ | ||
public function delete(string $key) | ||
{ | ||
return $this->getClientFromKey($key)->delete($key); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
* @throws \Flexihash\Exception | ||
*/ | ||
public function putIf(string $key, $value, $previousValue, bool $returnNewValueOnFail = false) | ||
{ | ||
return $this->getClientFromKey($key)->putIf($key, $value, $previousValue, $returnNewValueOnFail); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
* @throws \Flexihash\Exception | ||
*/ | ||
public function deleteIf(string $key, $previousValue, bool $returnNewValueOnFail = false) | ||
{ | ||
return $this->getClientFromKey($key)->deleteIf($key, $previousValue, $returnNewValueOnFail); | ||
} | ||
} |