Skip to content

Commit

Permalink
Optimize Redis keys loading
Browse files Browse the repository at this point in the history
  • Loading branch information
RobiNN1 committed Aug 31, 2024
1 parent d29831f commit 65a9559
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 28 deletions.
41 changes: 31 additions & 10 deletions src/Dashboards/Redis/Compatibility/Predis.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

use Predis\Client;
use Predis\Collection\Iterator\Keyspace;
use RobiNN\Pca\Dashboards\DashboardException;

class Predis extends Client implements RedisCompatibilityInterface {
use RedisJson;
Expand Down Expand Up @@ -56,17 +55,14 @@ public function __construct(array $server) {
]);
}

/**
* @throws DashboardException
*/
public function getType(string $key): string {
$type = (string) $this->type($key);
public function getType(string|int $type): string {
return $this->data_types[$type] ?? 'unknown';
}

if (!isset($this->data_types[$type])) {
throw new DashboardException(sprintf('Unsupported data type: %s', $type));
}
public function getKeyType(string $key): string {
$type = (string) $this->type($key);

return $this->data_types[$type];
return $this->getType($type);
}

/**
Expand Down Expand Up @@ -128,4 +124,29 @@ public function streamAdd(string $key, string $id, array $messages): string {
public function rawCommand(string $command, mixed ...$arguments): mixed {
return $this->executeRaw(func_get_args());
}

/**
* @param array<int, string> $keys
*
* @return array<string, mixed>
*/
public function pipelineKeys(array $keys): array {
$results = $this->pipeline(function ($pipe) use ($keys) {
foreach ($keys as $key) {
$pipe->ttl($key);
$pipe->type($key);
}
});

$data = [];

foreach ($keys as $i => $key) {
$data[$key] = [
'ttl' => $results[$i * 2],
'type' => $this->getType((string) $results[$i * 2 + 1]),
];
}

return $data;
}
}
43 changes: 36 additions & 7 deletions src/Dashboards/Redis/Compatibility/Redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,22 @@ public function connection(array $server): self {
return $this;
}

public function getType(string|int $type): string {
return $this->data_types[$type] ?? 'unknown';
}

/**
* @throws RedisException|DashboardException
* @throws RedisException
*/
public function getType(string $key): string {
public function getKeyType(string $key): string {
$type = $this->type($key);

if ($type === self::REDIS_NOT_FOUND) {
$this->setOption(self::OPT_REPLY_LITERAL, true);
$type = $this->rawCommand('TYPE', $key);
}

if (!isset($this->data_types[$type])) {
throw new DashboardException(sprintf('Unsupported data type: %s', $type));
}

return $this->data_types[$type];
return $this->getType($type);
}

/**
Expand Down Expand Up @@ -140,4 +140,33 @@ public function listRem(string $key, string $value, int $count): int {
public function streamAdd(string $key, string $id, array $messages): string {
return $this->xAdd($key, $id, $messages);
}

/**
* @param array<int, string> $keys
*
* @return array<string, mixed>
*
* @throws RedisException
*/
public function pipelineKeys(array $keys): array {
$pipeline = $this->multi(self::PIPELINE);

foreach ($keys as $key) {
$pipeline->ttl($key);
$pipeline->type($key);
}

$results = $pipeline->exec();

$data = [];

foreach ($keys as $i => $key) {
$data[$key] = [
'ttl' => $results[$i * 2],
'type' => $this->getType($results[$i * 2 + 1]),
];
}

return $data;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@
use RobiNN\Pca\Dashboards\DashboardException;

interface RedisCompatibilityInterface {
/**
* Get a key type from an array.
*/
public function getType(string|int $type): string;

/**
* Get a key type.
*
* @throws DashboardException
*/
public function getType(string $key): string;
public function getKeyType(string $key): string;

/**
* Get server info.
Expand All @@ -43,4 +48,13 @@ public function listRem(string $key, string $value, int $count): int;
* @param array<string, string> $messages
*/
public function streamAdd(string $key, string $id, array $messages): string;

/**
* Pipeline keys for better performance.
*
* @param array<int, string> $keys
*
* @return array<string, mixed>
*/
public function pipelineKeys(array $keys): array;
}
15 changes: 6 additions & 9 deletions src/Dashboards/Redis/RedisTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ private function viewKey(): string {
}

try {
$type = $this->redis->getType($key);
$type = $this->redis->getKeyType($key);
} catch (DashboardException $e) {
return $e->getMessage();
}
Expand Down Expand Up @@ -271,7 +271,7 @@ private function form(): string {
// edit|subkeys
if (isset($_GET['key']) && $this->redis->exists($key)) {
try {
$type = $this->redis->getType($key);
$type = $this->redis->getKeyType($key);
} catch (DashboardException $e) {
Helpers::alert($this->template, $e->getMessage(), 'error');
$type = 'unknown';
Expand Down Expand Up @@ -317,14 +317,11 @@ private function getAllKeys(): array {
$keys_array = $this->redis->keys($filter);
}

foreach ($keys_array as $key) {
try {
$type = $this->redis->getType($key);
} catch (DashboardException) {
$type = 'unknown';
}
$pipeline = $this->redis->pipelineKeys($keys_array);

$ttl = $this->redis->ttl($key);
foreach ($keys_array as $key) {
$ttl = $pipeline[$key]['ttl'];
$type = $pipeline[$key]['type'];
$total = $this->getCountOfItemsInKey($type, $key);

$keys[] = [
Expand Down
2 changes: 1 addition & 1 deletion tests/Clients/PredisTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function testGetType(string $key): void {
$this->predis->streamAdd('pu-pred-test-stream', '*', ['field1' => 'value1', 'field2' => 'value2']);
$this->predis->streamAdd('pu-pred-test-stream', '*', ['field3' => 'value3']);

$this->assertSame($key, $this->predis->getType('pu-pred-test-'.$key));
$this->assertSame($key, $this->predis->getKeyType('pu-pred-test-'.$key));
}

#[DataProvider('keysProvider')]
Expand Down

0 comments on commit 65a9559

Please sign in to comment.