diff --git a/src/Jobs/RetryFailedJob.php b/src/Jobs/RetryFailedJob.php index a2448383..55692100 100644 --- a/src/Jobs/RetryFailedJob.php +++ b/src/Jobs/RetryFailedJob.php @@ -77,8 +77,10 @@ protected function prepareNewTimeout($payload) { $retryUntil = $payload['retryUntil'] ?? $payload['timeoutAt'] ?? null; + $pushedAt = $payload['pushedAt'] ?? microtime(true); + return $retryUntil - ? CarbonImmutable::now()->addSeconds(ceil($retryUntil - $payload['pushedAt']))->getTimestamp() + ? CarbonImmutable::now()->addSeconds(ceil($retryUntil - $pushedAt))->getTimestamp() : null; } } diff --git a/tests/Feature/RetryJobTest.php b/tests/Feature/RetryJobTest.php index e85cbcc8..88419799 100644 --- a/tests/Feature/RetryJobTest.php +++ b/tests/Feature/RetryJobTest.php @@ -2,8 +2,11 @@ namespace Laravel\Horizon\Tests\Feature; +use Exception; use Illuminate\Support\Facades\Queue; use Illuminate\Support\Facades\Redis; +use Laravel\Horizon\Contracts\JobRepository; +use Laravel\Horizon\JobPayload; use Laravel\Horizon\Jobs\MonitorTag; use Laravel\Horizon\Jobs\RetryFailedJob; use Laravel\Horizon\Tests\IntegrationTest; @@ -79,4 +82,27 @@ public function test_status_is_updated_for_double_failing_jobs() // Test status is now failed on the retry... $this->assertSame('failed', $retried[0]['status']); } + + public function test_retrying_failed_job_with_retry_until_and_without_pushed_at() + { + $repository = $this->app->make(JobRepository::class); + + $payload = new JobPayload( + json_encode([ + 'id' => 1, + 'displayName' => 'foo', + 'retryUntil' => now()->addMinute()->timestamp, + ]) + ); + + $repository->failed(new Exception('Failed Job'), 'redis', 'default', $payload); + + dispatch(new RetryFailedJob(1)); + $this->work(); + + $retried = Redis::connection('horizon')->hget(1, 'retried_by'); + $retried = json_decode($retried, true); + + $this->assertSame('pending', $retried[0]['status']); + } }