Skip to content

Commit 8b41a80

Browse files
committed
2 parents 83f9d83 + b14cfc9 commit 8b41a80

File tree

6 files changed

+225
-6
lines changed

6 files changed

+225
-6
lines changed

src/Illuminate/Foundation/Testing/Concerns/InteractsWithRedis.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Illuminate\Foundation\Testing\Concerns;
44

55
use Illuminate\Redis\RedisManager;
6+
use Illuminate\Foundation\Application;
67

78
trait InteractsWithRedis
89
{
@@ -27,6 +28,7 @@ trait InteractsWithRedis
2728
*/
2829
public function setUpRedis()
2930
{
31+
$app = $this->app ?? new Application;
3032
$host = getenv('REDIS_HOST') ?: '127.0.0.1';
3133
$port = getenv('REDIS_PORT') ?: 6379;
3234

@@ -37,7 +39,7 @@ public function setUpRedis()
3739
}
3840

3941
foreach ($this->redisDriverProvider() as $driver) {
40-
$this->redis[$driver[0]] = new RedisManager($driver[0], [
42+
$this->redis[$driver[0]] = new RedisManager($app, $driver[0], [
4143
'cluster' => false,
4244
'default' => [
4345
'host' => $host,

src/Illuminate/Redis/Connections/Connection.php

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Illuminate\Redis\Connections;
44

55
use Closure;
6+
use Illuminate\Contracts\Events\Dispatcher;
7+
use Illuminate\Redis\Events\CommandExecuted;
68
use Illuminate\Redis\Limiters\DurationLimiterBuilder;
79
use Illuminate\Redis\Limiters\ConcurrencyLimiterBuilder;
810

@@ -25,6 +27,13 @@ abstract class Connection
2527
*/
2628
protected $name;
2729

30+
/**
31+
* The event dispatcher instance.
32+
*
33+
* @var \Illuminate\Contracts\Events\Dispatcher
34+
*/
35+
protected $events;
36+
2837
/**
2938
* Subscribe to a set of given channels for messages.
3039
*
@@ -100,7 +109,43 @@ public function psubscribe($channels, Closure $callback)
100109
*/
101110
public function command($method, array $parameters = [])
102111
{
103-
return $this->client->{$method}(...$parameters);
112+
$start = microtime(true);
113+
114+
$result = $this->client->{$method}(...$parameters);
115+
116+
$time = round((microtime(true) - $start) * 1000, 2);
117+
118+
if (isset($this->events)) {
119+
$this->event(new CommandExecuted($method, $parameters, $time, $this));
120+
}
121+
122+
return $result;
123+
}
124+
125+
/**
126+
* Fire the given event if possible.
127+
*
128+
* @param mixed $event
129+
* @return void
130+
*/
131+
protected function event($event)
132+
{
133+
if (isset($this->events)) {
134+
$this->events->dispatch($event);
135+
}
136+
}
137+
138+
/**
139+
* Register a Redis command listener with the connection.
140+
*
141+
* @param \Closure $callback
142+
* @return void
143+
*/
144+
public function listen(Closure $callback)
145+
{
146+
if (isset($this->events)) {
147+
$this->events->listen(CommandExecuted::class, $callback);
148+
}
104149
}
105150

106151
/**
@@ -126,6 +171,37 @@ public function setName($name)
126171
return $this;
127172
}
128173

174+
/**
175+
* Get the event dispatcher used by the connection.
176+
*
177+
* @return \Illuminate\Contracts\Events\Dispatcher
178+
*/
179+
public function getEventDispatcher()
180+
{
181+
return $this->events;
182+
}
183+
184+
/**
185+
* Set the event dispatcher instance on the connection.
186+
*
187+
* @param \Illuminate\Contracts\Events\Dispatcher $events
188+
* @return void
189+
*/
190+
public function setEventDispatcher(Dispatcher $events)
191+
{
192+
$this->events = $events;
193+
}
194+
195+
/**
196+
* Unset the event dispatcher instance on the connection.
197+
*
198+
* @return void
199+
*/
200+
public function unsetEventDispatcher()
201+
{
202+
$this->events = null;
203+
}
204+
129205
/**
130206
* Pass other method calls down to the underlying client.
131207
*
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace Illuminate\Redis\Events;
4+
5+
class CommandExecuted
6+
{
7+
/**
8+
* The Redis command that was executed.
9+
*
10+
* @var string
11+
*/
12+
public $command;
13+
14+
/**
15+
* The array of command parameters.
16+
*
17+
* @var array
18+
*/
19+
public $parameters;
20+
21+
/**
22+
* The number of milliseconds it took to execute the command.
23+
*
24+
* @var float
25+
*/
26+
public $time;
27+
28+
/**
29+
* The Redis connection instance.
30+
*
31+
* @var \Illuminate\Redis\Connections\Connection
32+
*/
33+
public $connection;
34+
35+
/**
36+
* The Redis connection name.
37+
*
38+
* @var string
39+
*/
40+
public $connectionName;
41+
42+
/**
43+
* Create a new event instance.
44+
*
45+
* @param string $command
46+
* @param array $parameters
47+
* @param float|null $time
48+
* @param \Illuminate\Redis\Connections\Connection $connection
49+
* @return void
50+
*/
51+
public function __construct($command, $parameters, $time, $connection)
52+
{
53+
$this->time = $time;
54+
$this->command = $command;
55+
$this->parameters = $parameters;
56+
$this->connection = $connection;
57+
$this->connectionName = $connection->getName();
58+
}
59+
}

src/Illuminate/Redis/RedisManager.php

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,20 @@
44

55
use InvalidArgumentException;
66
use Illuminate\Contracts\Redis\Factory;
7+
use Illuminate\Redis\Connections\Connection;
78

89
/**
910
* @mixin \Illuminate\Redis\Connections\Connection
1011
*/
1112
class RedisManager implements Factory
1213
{
14+
/**
15+
* The application instance.
16+
*
17+
* @var \Illuminate\Foundation\Application
18+
*/
19+
protected $app;
20+
1321
/**
1422
* The name of the default driver.
1523
*
@@ -31,15 +39,24 @@ class RedisManager implements Factory
3139
*/
3240
protected $connections;
3341

42+
/**
43+
* Indicates whether event dispatcher is set on connections.
44+
*
45+
* @var bool
46+
*/
47+
protected $events = false;
48+
3449
/**
3550
* Create a new Redis manager instance.
3651
*
52+
* @param \Illuminate\Foundation\Application $app
3753
* @param string $driver
3854
* @param array $config
3955
* @return void
4056
*/
41-
public function __construct($driver, array $config)
57+
public function __construct($app, $driver, array $config)
4258
{
59+
$this->app = $app;
4360
$this->driver = $driver;
4461
$this->config = $config;
4562
}
@@ -58,7 +75,9 @@ public function connection($name = null)
5875
return $this->connections[$name];
5976
}
6077

61-
return $this->connections[$name] = $this->resolve($name)->setName($name);
78+
return $this->connections[$name] = $this->configure(
79+
$this->resolve($name), $name
80+
);
6281
}
6382

6483
/**
@@ -101,6 +120,24 @@ protected function resolveCluster($name)
101120
);
102121
}
103122

123+
/**
124+
* Configure the given connection to prepare it for commands.
125+
*
126+
* @param \Illuminate\Redis\Connections\Connection $connection
127+
* @param string $name
128+
* @return \Illuminate\Redis\Connections\Connection
129+
*/
130+
protected function configure(Connection $connection, $name)
131+
{
132+
$connection->setName($name);
133+
134+
if ($this->events && $this->app->bound('events')) {
135+
$connection->setEventDispatcher($this->app->make('events'));
136+
}
137+
138+
return $connection;
139+
}
140+
104141
/**
105142
* Get the connector instance for the current driver.
106143
*
@@ -126,6 +163,26 @@ public function connections()
126163
return $this->connections;
127164
}
128165

166+
/**
167+
* Enable the firing of Redis command events.
168+
*
169+
* @return void
170+
*/
171+
public function enableEvents()
172+
{
173+
$this->events = true;
174+
}
175+
176+
/**
177+
* Disable the firing of Redis command events.
178+
*
179+
* @return void
180+
*/
181+
public function disableEvents()
182+
{
183+
$this->events = false;
184+
}
185+
129186
/**
130187
* Pass methods onto the default Redis connection.
131188
*

src/Illuminate/Redis/RedisServiceProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function register()
2424
$this->app->singleton('redis', function ($app) {
2525
$config = $app->make('config')->get('database.redis');
2626

27-
return new RedisManager(Arr::pull($config, 'client', 'predis'), $config);
27+
return new RedisManager($app, Arr::pull($config, 'client', 'predis'), $config);
2828
});
2929

3030
$this->app->bind('redis.connection', function ($app) {

tests/Redis/RedisConnectionTest.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
namespace Illuminate\Tests\Redis;
44

5+
use Mockery as m;
56
use PHPUnit\Framework\TestCase;
67
use Illuminate\Redis\RedisManager;
8+
use Illuminate\Foundation\Application;
79
use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis;
810

911
class RedisConnectionTest extends TestCase
@@ -573,6 +575,29 @@ public function it_runs_raw_command()
573575
}
574576
}
575577

578+
/**
579+
* @test
580+
*/
581+
public function it_dispatches_query_event()
582+
{
583+
foreach ($this->connections() as $redis) {
584+
$redis->setEventDispatcher($events = m::mock('Illuminate\Contracts\Events\Dispatcher'));
585+
586+
$events->shouldReceive('dispatch')->once()->with(m::on(function ($event) {
587+
$this->assertEquals('get', $event->command);
588+
$this->assertEquals(['foobar'], $event->parameters);
589+
$this->assertEquals('default', $event->connectionName);
590+
$this->assertInstanceOf('\Illuminate\Redis\Connections\Connection', $event->connection);
591+
592+
return true;
593+
}));
594+
595+
$redis->get('foobar');
596+
597+
$redis->unsetEventDispatcher();
598+
}
599+
}
600+
576601
public function connections()
577602
{
578603
$connections = [
@@ -584,7 +609,7 @@ public function connections()
584609
$host = getenv('REDIS_HOST') ?: '127.0.0.1';
585610
$port = getenv('REDIS_PORT') ?: 6379;
586611

587-
$prefixedPhpredis = new RedisManager('phpredis', [
612+
$prefixedPhpredis = new RedisManager(new Application, 'phpredis', [
588613
'cluster' => false,
589614
'default' => [
590615
'host' => $host,

0 commit comments

Comments
 (0)