Skip to content
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

Add RedisSharedClient that can share one connected driver for more clients #49

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions src/Kdyby/Redis/ConnectionPool.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

/**
* This file is part of the Kdyby (http://www.kdyby.org)
*
* Copyright (c) 2008 Filip Procházka (filip@prochazka.su)
*
* For the full copyright and license information, please view the file license.txt that was distributed with this source code.
*/

namespace Kdyby\Redis;

use Kdyby;
use Nette;



/**
* @author Filip Procházka <filip@prochazka.su>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here should be your name ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

He, yes, thanks :-)

*/
class ConnectionPool extends Nette\Object
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the name very much, because it's not accurate. I don't have an idea for a better one through...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, it is not pool and it is not for connections... What about something like DriverSharer or similar?

{

/**
* @var IRedisDriver[]
*/
private $connections = array();


/**
* Add new connection to pool
* @param string $host
* @param int $port
* @param IRedisDriver $connection
* @throws ConnectionAlreadyInPoolException
*/
public function addConnection($host, $port, IRedisDriver $connection)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of people also use sockets

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, that this will work also with sockets. You pass host = '/tmp/redis.sock' and port = NULL.

{
$key = $this->getKey($host, $port);

if (isset($this->connections[$key])) {
throw new ConnectionAlreadyInPoolException;
}

$this->connections[$key] = $connection;
}



/**
* Get connection from pool
* @param string $host
* @param int $port
* @return Driver\PhpRedisDriver
*/
public function getConnection($host, $port)
{
$key = $this->getKey($host, $port);

if (!isset($this->connections[$key])) {
return NULL;
}

return $this->connections[$key];
}



private function getKey($host, $port)
{
return strtolower($host) . ':' . $port;
}

}
24 changes: 23 additions & 1 deletion src/Kdyby/Redis/Driver/PhpRedisDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
class PhpRedisDriver extends \Redis implements Kdyby\Redis\IRedisDriver
{

/**
* @var integer
*/
private $database = 0;


/**
* {@inheritdoc}
*/
Expand All @@ -38,7 +44,13 @@ public function connect($host, $port = NULL, $timeout = 0)
public function select($database)
{
$args = func_get_args();
return call_user_func_array('parent::select', $args);
$result = call_user_func_array('parent::select', $args);

if ($result === TRUE) {
$this->database = (int) $database;
}

return $result;
}


Expand All @@ -63,4 +75,14 @@ public function evalsha($scriptSha, $argsArray = array(), $numKeys = 0)
return call_user_func_array('parent::evalsha', $args);
}



/**
* {@inheritdoc}
*/
public function getDatabase()
{
return $this->database;
}

}
7 changes: 7 additions & 0 deletions src/Kdyby/Redis/IRedisDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ function select($database);
*/
function close();

/**
* Get actual selected database
*
* @return int
*/
function getDatabase();

/**
* The last error message (if any)
*
Expand Down
35 changes: 33 additions & 2 deletions src/Kdyby/Redis/RedisClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class RedisClient extends Nette\Object implements \ArrayAccess
/**
* @var Driver\PhpRedisDriver
*/
private $driver;
protected $driver;

/**
* @var bool
Expand All @@ -183,7 +183,7 @@ class RedisClient extends Nette\Object implements \ArrayAccess
private $panel;

/**
* @var string
* @var int
*/
private $host;

Expand Down Expand Up @@ -261,6 +261,36 @@ public function __destruct()



/**
* @return string
*/
protected function getHost()
{
return $this->host;
}



/**
* @return int
*/
protected function getPort()
{
return $this->port;
}



/**
* @return int
*/
protected function getDatabase()
{
return $this->database;
}



/**
* @return \Kdyby\Redis\IRedisDriver
*/
Expand All @@ -279,6 +309,7 @@ public function connect()
}

if ($this->driver->isConnected()) {
$this->isConnected = TRUE;
return;
}

Expand Down
97 changes: 97 additions & 0 deletions src/Kdyby/Redis/RedisSharedClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

/**
* This file is part of the Kdyby (http://www.kdyby.org)
*
* Copyright (c) 2008 Filip Procházka (filip@prochazka.su)
*
* For the full copyright and license information, please view the file license.md that was distributed with this source code.
*/

namespace Kdyby\Redis;

use Kdyby;
use Nette;



/**
* @author Jakub Trmota <jakub@trmota.cz>
*/
class RedisSharedClient extends RedisClient
{

/**
* @var ConnectionPool
*/
private $connectionPool;


/**
* @param ConnectionPool $connectionPool
* @param string $host
* @param int $port
* @param int $database
* @param int $timeout
* @param string $auth
* @param bool $persistent
* @throws MissingExtensionException
*/
public function __construct(ConnectionPool $connectionPool, $host = '127.0.0.1', $port = NULL, $database = 0, $timeout = 10, $auth = NULL, $persistent = FALSE)
{
parent::__construct($host, $port, $database, $timeout, $auth, $persistent);
$this->connectionPool = $connectionPool;
}



public function connect()
{
if (!$this->driver) {
$driver = $this->connectionPool->getConnection($this->getHost(), $this->getPort());

if ($driver === NULL) {
$driver = new Driver\PhpRedisDriver();
$this->connectionPool->addConnection($this->getHost(), $this->getPort(), $driver);
}

$this->driver = $driver;
}

parent::connect();

$this->synchronizeClientDatabase();
}



/**
* {@inheritdoc}
*/
public function send($cmd, array $args = array())
{
if ($this->driver) {
if (!$this->driver->isConnected()) {
$this->connect();
}
$this->synchronizeClientDatabase();
}

return parent::send($cmd, $args);
}



/**
* @throws RedisClientException
*/
private function synchronizeClientDatabase()
{
if ($this->driver->getDatabase() != $this->getDatabase()) {
if (call_user_func_array(array($this->driver, 'select'), [$this->getDatabase()]) === FALSE) {
throw new RedisClientException('Can\'t set client database on driver');
}
}
}

}
10 changes: 10 additions & 0 deletions src/Kdyby/Redis/exceptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ class TransactionException extends RedisClientException implements Exception



/**
* @author Filip Procházka <filip@prochazka.su>
*/
class ConnectionAlreadyInPoolException extends \RuntimeException implements Exception
{

}



/**
* @author Filip Procházka <filip@prochazka.su>
*/
Expand Down
Loading