Skip to content

Commit

Permalink
Added Hyperf\Redis\Event\CommandExecuted event (#7269)
Browse files Browse the repository at this point in the history
Co-authored-by: 李铭昕 <[email protected]>
  • Loading branch information
huangdijia and limingxinleo authored Feb 6, 2025
1 parent 973a92c commit 4f4088a
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 0 deletions.
3 changes: 3 additions & 0 deletions publish/redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,8 @@
'options' => [
'prefix' => env('REDIS_PREFIX', ''),
],
'event' => [
'enable' => (bool) env('REDIS_EVENT_ENABLE', false),
],
],
];
34 changes: 34 additions & 0 deletions src/Event/CommandExecuted.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact [email protected]
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/

namespace Hyperf\Redis\Event;

use Hyperf\Redis\RedisConnection;
use Throwable;

class CommandExecuted
{
/**
* Create a new event instance.
* @param float $time duration in milliseconds
*/
public function __construct(
public string $command,
public array $parameters,
public ?float $time,
public RedisConnection $connection,
public string $connectionName,
public mixed $result,
public ?Throwable $throwable,
) {
}
}
20 changes: 20 additions & 0 deletions src/Redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Hyperf\Context\Context;
use Hyperf\Redis\Exception\InvalidRedisConnectionException;
use Hyperf\Redis\Pool\PoolFactory;
use Throwable;

use function Hyperf\Coroutine\defer;

Expand All @@ -37,12 +38,31 @@ public function __call($name, $arguments)
// Get a connection from coroutine context or connection pool.
$hasContextConnection = Context::has($this->getContextKey());
$connection = $this->getConnection($hasContextConnection);
// Record the start time of the command.
$start = (float) microtime(true);

try {
/** @var RedisConnection $connection */
$connection = $connection->getConnection();
// Execute the command with the arguments.
$result = $connection->{$name}(...$arguments);
} catch (Throwable $exception) {
throw $exception;
} finally {
$time = round((microtime(true) - $start) * 1000, 2);
// Dispatch the command executed event.
$connection->getEventDispatcher()?->dispatch(
new Event\CommandExecuted(
$name,
$arguments,
$time,
$connection,
$this->poolName,
$result ?? null,
$exception ?? null,
)
);

// Release connection.
if (! $hasContextConnection) {
if ($this->shouldUseSameConnection($name)) {
Expand Down
15 changes: 15 additions & 0 deletions src/RedisConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Hyperf\Redis\Exception\InvalidRedisConnectionException;
use Hyperf\Redis\Exception\InvalidRedisOptionException;
use Psr\Container\ContainerInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LogLevel;
use Redis;
use RedisCluster;
Expand All @@ -36,6 +37,8 @@ class RedisConnection extends BaseConnection implements ConnectionInterface

protected null|Redis|RedisCluster $connection = null;

protected ?EventDispatcherInterface $eventDispatcher = null;

protected array $config = [
'host' => 'localhost',
'port' => 6379,
Expand All @@ -62,6 +65,9 @@ class RedisConnection extends BaseConnection implements ConnectionInterface
],
'options' => [],
'context' => [],
'event' => [
'enable' => false,
],
];

/**
Expand Down Expand Up @@ -101,6 +107,11 @@ public function getActiveConnection()
return $this;
}

public function getEventDispatcher(): ?EventDispatcherInterface
{
return $this->eventDispatcher;
}

/**
* @throws RedisException
* @throws ConnectionException
Expand Down Expand Up @@ -150,6 +161,10 @@ public function reconnect(): bool
$this->connection = $redis;
$this->lastUseTime = microtime(true);

if (($this->config['event']['enable'] ?? false) && $this->container->has(EventDispatcherInterface::class)) {
$this->eventDispatcher = $this->container->get(EventDispatcherInterface::class);
}

return true;
}

Expand Down
3 changes: 3 additions & 0 deletions tests/RedisConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ public function testRedisConnectionConfig()
'context' => [
'stream' => ['cafile' => 'foo-cafile', 'verify_peer' => true],
],
'event' => [
'enable' => false,
],
'pool' => [
'min_connections' => 1,
'max_connections' => 30,
Expand Down

0 comments on commit 4f4088a

Please sign in to comment.