Skip to content

Commit 4b0dc8c

Browse files
refactor: replace StorageManager abstraction with direct Laravel Redis usage
Problem: - Complex abstraction layer (StorageManager + StorageDriver interface) - Difficult prefix handling with phpredis - Over-engineered for simple Redis operations Solution: - Created RedisMetricsStore - simple wrapper around Laravel's Redis facade - Laravel handles all prefix logic automatically and consistently - Removed need for separate driver implementations - Same interface as before, but simpler implementation Benefits: - Leverages Laravel's Redis connection directly (no reinventing wheel) - Consistent prefix behavior (Laravel handles it) - Easier to debug (less abstraction layers) - More maintainable (less custom code) - Still supports configurable connection via queue-metrics.storage.connection Implementation: 1. Created Support/RedisMetricsStore with StorageDriver-compatible interface 2. Updated ServiceProvider to use RedisMetricsStore instead of StorageManager 3. Updated all repositories to inject RedisMetricsStore 4. Updated MetricsQueryService to use new store Next: Remove old Storage classes (will do after testing) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent b4e88c9 commit 4b0dc8c

9 files changed

+351
-26
lines changed

src/LaravelQueueMetricsServiceProvider.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
use PHPeek\LaravelQueueMetrics\Services\LaravelQueueInspector;
4848
use PHPeek\LaravelQueueMetrics\Services\MetricsQueryService;
4949
use PHPeek\LaravelQueueMetrics\Services\ServerMetricsService;
50-
use PHPeek\LaravelQueueMetrics\Storage\StorageManager;
50+
use PHPeek\LaravelQueueMetrics\Support\RedisMetricsStore;
5151
use PHPeek\LaravelQueueMetrics\Utilities\PercentileCalculator;
5252
use Gophpeek\SystemMetrics\SystemMetrics;
5353
use Spatie\LaravelPackageTools\Package;
@@ -77,30 +77,30 @@ public function packageRegistered(): void
7777
return $app->make(QueueMetricsConfig::class)->storage;
7878
});
7979

80-
// Register storage manager
81-
$this->app->singleton(StorageManager::class, function ($app) {
82-
return new StorageManager($app->make(StorageConfig::class));
80+
// Register Redis metrics store - uses Laravel's Redis connection directly
81+
$this->app->singleton(RedisMetricsStore::class, function () {
82+
return new RedisMetricsStore();
8383
});
8484

85-
// Register repositories - all use StorageManager
85+
// Register repositories - all use RedisMetricsStore
8686
$this->app->singleton(JobMetricsRepository::class, function ($app) {
87-
return new RedisJobMetricsRepository($app->make(StorageManager::class));
87+
return new RedisJobMetricsRepository($app->make(RedisMetricsStore::class));
8888
});
8989

9090
$this->app->singleton(QueueMetricsRepository::class, function ($app) {
91-
return new RedisQueueMetricsRepository($app->make(StorageManager::class));
91+
return new RedisQueueMetricsRepository($app->make(RedisMetricsStore::class));
9292
});
9393

9494
$this->app->singleton(WorkerRepository::class, function ($app) {
95-
return new RedisWorkerRepository($app->make(StorageManager::class));
95+
return new RedisWorkerRepository($app->make(RedisMetricsStore::class));
9696
});
9797

9898
$this->app->singleton(BaselineRepository::class, function ($app) {
99-
return new RedisBaselineRepository($app->make(StorageManager::class));
99+
return new RedisBaselineRepository($app->make(RedisMetricsStore::class));
100100
});
101101

102102
$this->app->singleton(WorkerHeartbeatRepository::class, function ($app) {
103-
return new RedisWorkerHeartbeatRepository($app->make(StorageManager::class));
103+
return new RedisWorkerHeartbeatRepository($app->make(RedisMetricsStore::class));
104104
});
105105

106106
// Register system metrics

src/Repositories/RedisBaselineRepository.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
use Carbon\Carbon;
88
use PHPeek\LaravelQueueMetrics\DataTransferObjects\BaselineData;
99
use PHPeek\LaravelQueueMetrics\Repositories\Contracts\BaselineRepository;
10-
use PHPeek\LaravelQueueMetrics\Storage\StorageManager;
10+
use PHPeek\LaravelQueueMetrics\Support\RedisMetricsStore;
1111

1212
/**
1313
* Redis-based implementation of baseline repository.
1414
*/
1515
final readonly class RedisBaselineRepository implements BaselineRepository
1616
{
1717
public function __construct(
18-
private StorageManager $redis,
18+
private RedisMetricsStore $redis,
1919
) {}
2020

2121
public function storeBaseline(BaselineData $baseline): void

src/Repositories/RedisJobMetricsRepository.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
use Carbon\Carbon;
88
use Illuminate\Redis\Connections\Connection;
99
use PHPeek\LaravelQueueMetrics\Repositories\Contracts\JobMetricsRepository;
10-
use PHPeek\LaravelQueueMetrics\Storage\StorageManager;
10+
use PHPeek\LaravelQueueMetrics\Support\RedisMetricsStore;
1111

1212
/**
1313
* Redis-based implementation of job metrics repository.
1414
*/
1515
final readonly class RedisJobMetricsRepository implements JobMetricsRepository
1616
{
1717
public function __construct(
18-
private StorageManager $redis,
18+
private RedisMetricsStore $redis,
1919
) {}
2020

2121
public function recordStart(

src/Repositories/RedisQueueMetricsRepository.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
use Carbon\Carbon;
88
use Illuminate\Support\Facades\Queue;
99
use PHPeek\LaravelQueueMetrics\Repositories\Contracts\QueueMetricsRepository;
10-
use PHPeek\LaravelQueueMetrics\Storage\StorageManager;
10+
use PHPeek\LaravelQueueMetrics\Support\RedisMetricsStore;
1111

1212
/**
1313
* Redis-based implementation of queue metrics repository.
1414
*/
1515
final readonly class RedisQueueMetricsRepository implements QueueMetricsRepository
1616
{
1717
public function __construct(
18-
private StorageManager $redis,
18+
private RedisMetricsStore $redis,
1919
) {}
2020

2121
/**

src/Repositories/RedisWorkerHeartbeatRepository.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99
use PHPeek\LaravelQueueMetrics\DataTransferObjects\WorkerHeartbeat;
1010
use PHPeek\LaravelQueueMetrics\Enums\WorkerState;
1111
use PHPeek\LaravelQueueMetrics\Repositories\Contracts\WorkerHeartbeatRepository;
12-
use PHPeek\LaravelQueueMetrics\Storage\StorageManager;
12+
use PHPeek\LaravelQueueMetrics\Support\RedisMetricsStore;
1313

1414
/**
1515
* Redis-based implementation of worker heartbeat repository.
1616
*/
1717
final readonly class RedisWorkerHeartbeatRepository implements WorkerHeartbeatRepository
1818
{
1919
public function __construct(
20-
private StorageManager $redis,
20+
private RedisMetricsStore $redis,
2121
) {}
2222

2323
public function recordHeartbeat(

src/Repositories/RedisWorkerRepository.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
use Carbon\Carbon;
88
use PHPeek\LaravelQueueMetrics\DataTransferObjects\WorkerStatsData;
99
use PHPeek\LaravelQueueMetrics\Repositories\Contracts\WorkerRepository;
10-
use PHPeek\LaravelQueueMetrics\Storage\StorageManager;
10+
use PHPeek\LaravelQueueMetrics\Support\RedisMetricsStore;
1111

1212
/**
1313
* Redis-based implementation of worker repository.
1414
*/
1515
final readonly class RedisWorkerRepository implements WorkerRepository
1616
{
1717
public function __construct(
18-
private StorageManager $redis,
18+
private RedisMetricsStore $redis,
1919
) {}
2020

2121
public function registerWorker(

src/Services/MetricsQueryService.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,14 @@ public function getOverview(): array
9595
$totalFailed = 0;
9696

9797
// Scan Redis for all job metrics keys and aggregate
98-
$manager = app(\PHPeek\LaravelQueueMetrics\Storage\StorageManager::class);
98+
$store = app(\PHPeek\LaravelQueueMetrics\Support\RedisMetricsStore::class);
9999

100100
// Laravel's Redis connection automatically adds prefix for KEYS command
101101
// So we only use our package prefix, not Laravel's Redis prefix
102-
$pattern = $manager->key('jobs', '*', '*', '*');
103-
104-
$driver = $manager->driver();
102+
$pattern = $store->key('jobs', '*', '*', '*');
105103

106104
// Get all job metrics keys
107-
$keys = $driver->scanKeys($pattern);
105+
$keys = $store->scanKeys($pattern);
108106

109107
// Laravel's Redis prefix for stripping
110108
$laravelPrefix = config('database.redis.options.prefix', '');
@@ -117,7 +115,7 @@ public function getOverview(): array
117115
? str_replace($laravelPrefix, '', $fullKey)
118116
: $fullKey;
119117

120-
$data = $driver->getHash($relativeKey);
118+
$data = $store->getHash($relativeKey);
121119
if (is_array($data)) {
122120
$totalProcessed += (int) ($data['total_processed'] ?? 0);
123121
$totalFailed += (int) ($data['total_failed'] ?? 0);

src/Support/MetricsKeyBuilder.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPeek\LaravelQueueMetrics\Support;
6+
7+
/**
8+
* Helper for building Redis keys with consistent prefixing.
9+
*/
10+
final readonly class MetricsKeyBuilder
11+
{
12+
private string $prefix;
13+
14+
public function __construct(?string $prefix = null)
15+
{
16+
$this->prefix = $prefix ?? config('queue-metrics.storage.prefix', 'queue_metrics');
17+
}
18+
19+
/**
20+
* Build a Redis key from segments.
21+
*/
22+
public function key(string ...$segments): string
23+
{
24+
return $this->prefix . ':' . implode(':', $segments);
25+
}
26+
27+
/**
28+
* Get TTL for a given key type.
29+
*/
30+
public function getTtl(string $type): int
31+
{
32+
return config("queue-metrics.storage.ttl.{$type}", 3600);
33+
}
34+
}

0 commit comments

Comments
 (0)