From 806b301864420d8a5a35d239f29c77d5a1a53fa1 Mon Sep 17 00:00:00 2001 From: Derek Date: Sun, 7 Jul 2019 17:04:09 -0400 Subject: [PATCH] Allow custom dashboard failed jobs metric Add config('horizon.trim.recent_failed') to control the dashboard "Failed Jobs" metric period. By default, it will be the past 7 days. --- config/horizon.php | 1 + .../Controllers/DashboardStatsController.php | 4 +-- src/Repositories/RedisJobRepository.php | 33 ++++++++++++++++++- .../DashboardStatsControllerTest.php | 2 +- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/config/horizon.php b/config/horizon.php index 69cdc5f0..c63a9a3f 100644 --- a/config/horizon.php +++ b/config/horizon.php @@ -95,6 +95,7 @@ 'trim' => [ 'recent' => 60, + 'recent_failed' => 10080, 'failed' => 10080, 'monitored' => 10080, ], diff --git a/src/Http/Controllers/DashboardStatsController.php b/src/Http/Controllers/DashboardStatsController.php index a6ce9db3..88d77119 100644 --- a/src/Http/Controllers/DashboardStatsController.php +++ b/src/Http/Controllers/DashboardStatsController.php @@ -22,12 +22,12 @@ public function index() 'processes' => $this->totalProcessCount(), 'queueWithMaxRuntime' => app(MetricsRepository::class)->queueWithMaximumRuntime(), 'queueWithMaxThroughput' => app(MetricsRepository::class)->queueWithMaximumThroughput(), - 'failedJobs' => app(JobRepository::class)->countFailed(), + 'failedJobs' => app(JobRepository::class)->countRecentlyFailed(), 'recentJobs' => app(JobRepository::class)->countRecent(), 'status' => $this->currentStatus(), 'wait' => collect(app(WaitTimeCalculator::class)->calculate())->take(1), 'periods' => [ - 'failedJobs' => config('horizon.trim.failed'), + 'failedJobs' => config('horizon.trim.recent_failed', config('horizon.trim.recent')), 'recentJobs' => config('horizon.trim.recent'), ], ]; diff --git a/src/Repositories/RedisJobRepository.php b/src/Repositories/RedisJobRepository.php index b48a0438..d1575310 100644 --- a/src/Repositories/RedisJobRepository.php +++ b/src/Repositories/RedisJobRepository.php @@ -28,6 +28,13 @@ class RedisJobRepository implements JobRepository 'exception', 'failed_at', 'completed_at', 'retried_by', 'reserved_at', ]; + /** + * The number of minutes until recently failed jobs should be purged. + * + * @var int + */ + public $recentFailedJobExpires; + /** * The number of minutes until recent jobs should be purged. * @@ -60,6 +67,7 @@ public function __construct(RedisFactory $redis) $this->redis = $redis; $this->recentJobExpires = config('horizon.trim.recent', 60); $this->failedJobExpires = config('horizon.trim.failed', 10080); + $this->recentFailedJobExpires = config('horizon.trim.recent_failed', $this->failedJobExpires); $this->monitoredJobExpires = config('horizon.trim.monitored', 10080); } @@ -164,17 +172,36 @@ protected function getJobsByType($type, $afterIndex) /** * Get the number of jobs in a given type set. * + * @param string $type * @return int */ protected function countJobsByType($type) { - $minutes = $type === 'failed_jobs' ? $this->failedJobExpires : $this->recentJobExpires; + $minutes = $this->minutesForType($type); return $this->connection()->zcount( $type, '-inf', Chronos::now()->subMinutes($minutes)->getTimestamp() * -1 ); } + /** + * Get the number of minutes to count for a given type set. + * + * @param string $type + * @return int + */ + protected function minutesForType($type) + { + switch ($type) { + case 'failed_jobs': + return $this->failedJobExpires; + case 'recent_failed_jobs': + return $this->recentFailedJobExpires; + default: + return $this->recentJobExpires; + } + } + /** * Retrieve the jobs with the given IDs. * @@ -445,6 +472,10 @@ public function trimRecentJobs() $pipe->zremrangebyscore('recent_jobs', $score, '+inf'); + if ($this->recentJobExpires !== $this->recentFailedJobExpires) { + $score = Chronos::now()->subMinutes($this->recentFailedJobExpires)->getTimestamp() * -1; + } + $pipe->zremrangebyscore('recent_failed_jobs', $score, '+inf'); }); } diff --git a/tests/Controller/DashboardStatsControllerTest.php b/tests/Controller/DashboardStatsControllerTest.php index f9545f00..fae3878d 100644 --- a/tests/Controller/DashboardStatsControllerTest.php +++ b/tests/Controller/DashboardStatsControllerTest.php @@ -38,7 +38,7 @@ public function test_all_stats_are_correctly_returned() $this->app->instance(MetricsRepository::class, $metrics); $jobs = Mockery::mock(JobRepository::class); - $jobs->shouldReceive('countFailed')->andReturn(1); + $jobs->shouldReceive('countRecentlyFailed')->andReturn(1); $jobs->shouldReceive('countRecent')->andReturn(1); $this->app->instance(JobRepository::class, $jobs);