-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementing PhpRedis client #36
Open
jeffreyzant
wants to merge
18
commits into
monospice:2.x
Choose a base branch
from
SLASH2NL:phpredis
base: 2.x
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
9079c94
implementing phpredis
jeffreyzant 9c0093d
implementing update_sentinels
jeffreyzant 56662b2
wrap all phpredis methods with retryOnFailure
jeffreyzant ef688e1
removing null coalescing operators
jeffreyzant 81e95f9
phpredis integration tests
jeffreyzant dec46c3
improving readability and integration tests
jeffreyzant d2a53a5
install pecl redis on travis
jeffreyzant 4f555d2
travis ci pecl without sudo
jeffreyzant eff0fef
travis ci pecl only php 7
jeffreyzant 923875e
travis ci pecl only php 7, edit install lines
jeffreyzant 46cdf3a
fixing travis pecl
jeffreyzant 03faa65
check if pecl extesion is enabled for tests
jeffreyzant 7681bcf
improve tests skipping
jeffreyzant 165ec41
fixing travis ci
jeffreyzant dcd0370
fixing laravel 5 PhpRedisConnection
jeffreyzant a60ce79
implementing retries on first connection
jeffreyzant e6e623a
working on merge request feedback
jeffreyzant 0f69a2b
Add Laravel 9.x Compatibility
jeffreyzant File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
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,227 @@ | ||
<?php | ||
|
||
namespace Monospice\LaravelRedisSentinel\Connections; | ||
|
||
use Closure; | ||
use Illuminate\Redis\Connections\PhpRedisConnection as LaravelPhpRedisConnection; | ||
use Monospice\LaravelRedisSentinel\Connectors\PhpRedisConnector; | ||
use Redis; | ||
use RedisException; | ||
|
||
/** | ||
* Executes Redis commands using the PhpRedis client. | ||
* | ||
* This package extends Laravel's PhpRedisConnection class to wrap all command | ||
* methods with a retryOnFailure method. | ||
* | ||
* @category Package | ||
* @package Monospice\LaravelRedisSentinel | ||
* @author Jeffrey Zant <[email protected]> | ||
* @license See LICENSE file | ||
* @link https://github.com/monospice/laravel-redis-sentinel-drivers | ||
*/ | ||
class PhpRedisConnection extends LaravelPhpRedisConnection | ||
{ | ||
/** | ||
* The connection creation callback. | ||
* | ||
* Laravel 5 does not store the connector by default. | ||
* | ||
* @var callable|null | ||
*/ | ||
protected $connector; | ||
|
||
/** | ||
* The number of times the client attempts to retry a command when it fails | ||
* to connect to a Redis instance behind Sentinel. | ||
* | ||
* @var int | ||
*/ | ||
protected $retryLimit = 20; | ||
jeffreyzant marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* The time in milliseconds to wait before the client retries a failed | ||
* command. | ||
* | ||
* @var int | ||
*/ | ||
protected $retryWait = 1000; | ||
|
||
/** | ||
* Create a new PhpRedis connection. | ||
* | ||
* @param \Redis $client | ||
* @param callable|null $connector | ||
* @param array $sentinelOptions | ||
* @return void | ||
*/ | ||
public function __construct($client, callable $connector = null, array $sentinelOptions = []) | ||
{ | ||
parent::__construct($client, $connector); | ||
|
||
// Set the connector when it is not set. Used for Laravel 5. | ||
if (! $this->connector) { | ||
$this->connector = $connector; | ||
} | ||
|
||
// Set the retry limit. | ||
if (isset($sentinelOptions['retry_limit']) && is_numeric($sentinelOptions['retry_limit'])) { | ||
$this->retryLimit = (int) $sentinelOptions['retry_limit']; | ||
} | ||
|
||
// Set the retry wait. | ||
if (isset($sentinelOptions['retry_wait']) && is_numeric($sentinelOptions['retry_wait'])) { | ||
$this->retryWait = (int) $sentinelOptions['retry_wait']; | ||
} | ||
} | ||
|
||
/** | ||
* {@inheritdoc} in addition retry on client failure. | ||
* | ||
* @param mixed $cursor | ||
* @param array $options | ||
* @return mixed | ||
*/ | ||
public function scan($cursor, $options = []) | ||
{ | ||
return $this->retryOnFailure(function () use ($cursor, $options) { | ||
return parent::scan($cursor, $options); | ||
}); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} in addition retry on client failure. | ||
* | ||
* @param string $key | ||
* @param mixed $cursor | ||
* @param array $options | ||
* @return mixed | ||
*/ | ||
public function zscan($key, $cursor, $options = []) | ||
{ | ||
return $this->retryOnFailure(function () use ($key, $cursor, $options) { | ||
parent::zscan($key, $cursor, $options); | ||
}); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} in addition retry on client failure. | ||
* | ||
* @param string $key | ||
* @param mixed $cursor | ||
* @param array $options | ||
* @return mixed | ||
*/ | ||
public function hscan($key, $cursor, $options = []) | ||
{ | ||
return $this->retryOnFailure(function () use ($key, $cursor, $options) { | ||
parent::hscan($key, $cursor, $options); | ||
}); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} in addition retry on client failure. | ||
* | ||
* @param string $key | ||
* @param mixed $cursor | ||
* @param array $options | ||
* @return mixed | ||
*/ | ||
public function sscan($key, $cursor, $options = []) | ||
{ | ||
return $this->retryOnFailure(function () use ($key, $cursor, $options) { | ||
parent::sscan($key, $cursor, $options); | ||
}); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} in addition retry on client failure. | ||
* | ||
* @param callable|null $callback | ||
* @return \Redis|array | ||
*/ | ||
public function pipeline(callable $callback = null) | ||
{ | ||
return $this->retryOnFailure(function () use ($callback) { | ||
return parent::pipeline($callback); | ||
}); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} in addition retry on client failure. | ||
* | ||
* @param callable|null $callback | ||
* @return \Redis|array | ||
*/ | ||
public function transaction(callable $callback = null) | ||
{ | ||
return $this->retryOnFailure(function () use ($callback) { | ||
return parent::transaction($callback); | ||
}); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} in addition retry on client failure. | ||
* | ||
* @param array|string $channels | ||
* @param \Closure $callback | ||
* @return void | ||
*/ | ||
public function subscribe($channels, Closure $callback) | ||
{ | ||
return $this->retryOnFailure(function () use ($channels, $callback) { | ||
return parent::subscribe($channels, $callback); | ||
}); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} in addition retry on client failure. | ||
* | ||
* @param array|string $channels | ||
* @param \Closure $callback | ||
* @return void | ||
*/ | ||
public function psubscribe($channels, Closure $callback) | ||
{ | ||
return $this->retryOnFailure(function () use ($channels, $callback) { | ||
return parent::psubscribe($channels, $callback); | ||
}); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} in addition retry on client failure. | ||
* | ||
* @param string $method | ||
* @param array $parameters | ||
* @return mixed | ||
*/ | ||
public function command($method, array $parameters = []) | ||
{ | ||
return $this->retryOnFailure(function () use ($method, $parameters) { | ||
return parent::command($method, $parameters); | ||
}); | ||
} | ||
|
||
/** | ||
* Attempt to retry the provided operation when the client fails to connect | ||
* to a Redis server. | ||
* | ||
* @param callable $callback The operation to execute. | ||
* @return mixed The result of the first successful attempt. | ||
*/ | ||
protected function retryOnFailure(callable $callback) | ||
{ | ||
return PhpRedisConnector::retryOnFailure($callback, $this->retryLimit, $this->retryWait, function () { | ||
$this->client->close(); | ||
|
||
try { | ||
if ($this->connector) { | ||
$this->client = call_user_func($this->connector); | ||
} | ||
} catch (RedisException $e) { | ||
// Ignore when the creation of a new client gets an exception. | ||
// If this exception isn't caught the retry will stop. | ||
} | ||
}); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do these configuration paramters play together with
retry_limit
andretry_wait
? Would it be possible to allow thePhpRedisConnection
to reuse the connector logic (and retry configuration) ofPhpRedisConnector
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These settings allow for a different configuration on first connection. So the normal
retry_limit
andretry_wait
are used for reconnecting after a failure. Theconnector_
options are used when creating the connection for the first time.I've combined some of the retry logic, but I can't seem to find a way to simplify this. Maybe you have some ideas about it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the settings are fine, just a bit hard to understand in combination with the other ones (which have quite similar names too). Explaining their difference from the similar named settings is probably all you can do at this point.