Skip to content

Commit ea9676c

Browse files
committed
[transport] Add redis backed transport.
0 parents  commit ea9676c

20 files changed

+1483
-0
lines changed

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*~
2+
/composer.lock
3+
/composer.phar
4+
/phpunit.xml
5+
/vendor/
6+
/.idea/

.travis.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
sudo: false
2+
3+
git:
4+
depth: 1
5+
6+
language: php
7+
8+
php:
9+
- '5.6'
10+
- '7.0'
11+
12+
cache:
13+
directories:
14+
- $HOME/.composer/cache
15+
16+
install:
17+
- composer self-update
18+
- composer install --prefer-source
19+
20+
script:
21+
- vendor/bin/phpunit --exclude-group=functional

LICENSE

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
The MIT License (MIT)
2+
Copyright (c) 2017 Forma-Pro
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is furnished
9+
to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all
12+
copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
THE SOFTWARE.

PRedis.php

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
namespace Enqueue\Redis;
3+
4+
use Predis\ClientInterface;
5+
use Predis\Response\ServerException as PRedisServerException;
6+
7+
class PRedis implements Redis
8+
{
9+
/**
10+
* @var ClientInterface
11+
*/
12+
private $redis;
13+
14+
/**
15+
* @param ClientInterface $redis
16+
*/
17+
public function __construct(ClientInterface $redis)
18+
{
19+
$this->redis = $redis;
20+
}
21+
22+
/**
23+
* {@inheritdoc}
24+
*/
25+
public function lpush($key, $value)
26+
{
27+
try {
28+
$this->redis->lpush($key, [$value]);
29+
} catch (PRedisServerException $e) {
30+
throw new ServerException('lpush command has failed', null, $e);
31+
}
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function brpop($key, $timeout)
38+
{
39+
try {
40+
return $this->brpop($key, (int) $timeout / 1000);
41+
} catch (PRedisServerException $e) {
42+
throw new ServerException('brpop command has failed', null, $e);
43+
}
44+
}
45+
46+
/**
47+
* {@inheritdoc}
48+
*/
49+
public function rpop($key)
50+
{ try {
51+
return $this->rpop($key);
52+
} catch (PRedisServerException $e) {
53+
throw new ServerException('rpop command has failed', null, $e);
54+
}
55+
}
56+
57+
public function connect()
58+
{
59+
$this->redis->connect();
60+
}
61+
62+
public function disconnect()
63+
{
64+
$this->redis->disconnect();
65+
}
66+
}

PhpRedis.php

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
namespace Enqueue\Redis;
3+
4+
class PhpRedis implements Redis
5+
{
6+
/**
7+
* @var \Redis
8+
*/
9+
private $redis;
10+
11+
/**
12+
* @var array
13+
*/
14+
private $config;
15+
16+
/**
17+
* @param \Redis $redis
18+
* @param array $config
19+
*/
20+
public function __construct(\Redis $redis, array $config)
21+
{
22+
$this->redis = $redis;
23+
24+
$this->config = array_replace([
25+
'host' => null,
26+
'port' => null,
27+
'timeout' => null,
28+
'reserved' => null,
29+
'retry_interval' => null,
30+
'persisted' => false,
31+
], $config);
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function lpush($key, $value)
38+
{
39+
if (false == $this->redis->lPush($key, $value)) {
40+
throw new ServerException($this->redis->getLastError());
41+
}
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public function brpop($key, $timeout)
48+
{
49+
if ($result = $this->redis->brPop([$key], $timeout)) {
50+
return $result[1];
51+
}
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function rpop($key)
58+
{
59+
return $this->redis->rPop($key);
60+
}
61+
62+
public function connect()
63+
{
64+
if (false == $this->redis) {
65+
$this->redis = new \Redis();
66+
67+
if ($this->config['persisted']) {
68+
$this->redis->pconnect(
69+
$this->config['host'],
70+
$this->config['port'],
71+
$this->config['timeout']
72+
);
73+
} else {
74+
$this->redis->connect(
75+
$this->config['host'],
76+
$this->config['port'],
77+
$this->config['timeout'],
78+
$this->config['reserved'],
79+
$this->config['retry_interval']
80+
);
81+
}
82+
}
83+
84+
return $this->redis;
85+
}
86+
87+
public function disconnect()
88+
{
89+
if ($this->redis) {
90+
$this->redis->close();
91+
}
92+
}
93+
}

README.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Redis Transport
2+
3+
[![Gitter](https://badges.gitter.im/php-enqueue/Lobby.svg)](https://gitter.im/php-enqueue/Lobby)
4+
[![Build Status](https://travis-ci.org/php-enqueue/redis-ext.png?branch=master)](https://travis-ci.org/php-enqueue/redis-ext)
5+
[![Total Downloads](https://poser.pugx.org/enqueue/redis-ext/d/total.png)](https://packagist.org/packages/enqueue/redis-ext)
6+
[![Latest Stable Version](https://poser.pugx.org/enqueue/redis-ext/version.png)](https://packagist.org/packages/enqueue/redis-ext)
7+
8+
This is an implementation of PSR specification. It allows you to send and consume message with Redis store as a broker.
9+
10+
## Resources
11+
12+
* [Documentation](https://github.com/php-enqueue/enqueue-dev/blob/master/docs/index.md)
13+
* [Questions](https://gitter.im/php-enqueue/Lobby)
14+
* [Issue Tracker](https://github.com/php-enqueue/enqueue-dev/issues)
15+
16+
## License
17+
18+
It is released under the [MIT License](LICENSE).

Redis.php

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
namespace Enqueue\Redis;
3+
4+
interface Redis
5+
{
6+
/**
7+
* @param string $key
8+
* @param string $value
9+
*
10+
* @return int length of the list
11+
*/
12+
public function lpush($key, $value);
13+
14+
/**
15+
* @param string $key
16+
* @param int $timeout in seconds
17+
*
18+
* @return string|null
19+
*/
20+
public function brpop($key, $timeout);
21+
22+
/**
23+
* @param string $key
24+
*
25+
* @return string|null
26+
*/
27+
public function rpop($key);
28+
29+
public function connect();
30+
31+
public function disconnect();
32+
}

RedisConnectionFactory.php

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
namespace Enqueue\Redis;
4+
5+
use Enqueue\Psr\PsrConnectionFactory;
6+
use Predis\Client;
7+
8+
class RedisConnectionFactory implements PsrConnectionFactory
9+
{
10+
/**
11+
* @var array
12+
*/
13+
private $config;
14+
15+
/**
16+
* @var \Redis
17+
*/
18+
private $redis;
19+
20+
/**
21+
* $config = [
22+
* 'host' => can be a host, or the path to a unix domain socket
23+
* 'port' => optional
24+
* 'timeout' => value in seconds (optional, default is 0.0 meaning unlimited)
25+
* 'reserved' => should be null if $retry_interval is specified
26+
* 'retry_interval' => retry interval in milliseconds.
27+
* 'vendor' => 'The library used internally to interact with Redis server
28+
* 'persisted' => bool, Whether it use single persisted connection or open a new one for every context
29+
* 'lazy' => the connection will be performed as later as possible, if the option set to true
30+
* ].
31+
*
32+
* @param $config
33+
*/
34+
public function __construct(array $config)
35+
{
36+
$this->config = array_replace([
37+
'host' => null,
38+
'port' => null,
39+
'timeout' => null,
40+
'reserved' => null,
41+
'retry_interval' => null,
42+
'vendor' => 'phpredis',
43+
'persisted' => false,
44+
'lazy' => true,
45+
], $config);
46+
47+
$supportedVendors = ['predis', 'phpredis'];
48+
if (false == in_array($this->config['vendor'], $supportedVendors)) {
49+
throw new \LogicException(sprintf(
50+
'Unsupported redis vendor given. It must be either "%s". Got "%s"',
51+
implode('", "', $supportedVendors),
52+
$this->config['vendor']
53+
));
54+
}
55+
}
56+
57+
/**
58+
* {@inheritdoc}
59+
*
60+
* @return RedisContext
61+
*/
62+
public function createContext()
63+
{
64+
if ($this->config['lazy']) {
65+
return new RedisContext(function () {
66+
$redis = $this->createRedis();
67+
$redis->connect();
68+
69+
return $redis;
70+
});
71+
}
72+
73+
return new RedisContext($this->createRedis());
74+
}
75+
76+
/**
77+
* @return Redis
78+
*/
79+
private function createRedis()
80+
{
81+
if ('phpredis' == $this->config['vendor'] && false == $this->redis) {
82+
$this->redis = new PhpRedis(new \Redis(), $this->config);
83+
}
84+
85+
if ('predis' == $this->config['vendor'] && false == $this->redis) {
86+
$this->redis = new PRedis(new Client($this->config, ['exceptions' => true]));
87+
}
88+
89+
return $this->redis;
90+
}
91+
}

0 commit comments

Comments
 (0)