'Laravel queues max attempts exceeded exception
I really need help. Because I've searched everywhere, tried it in different ways, but I'm still missing something. I have this error:
local.ERROR: App\Jobs\TestJob has been attempted too many times or run too long. The job may have previously timed out. {"exception":"[object] (Illuminate\Queue\MaxAttemptsExceededException(code: 0): App\Jobs\TestJob has been attempted too many times or run too long. The job may have previously timed out. at /app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php:750)
Below is how I implemented the queue.
Creating queue:
use App\Jobs\Middleware\RateLimited;
Testjob::dispatch($data, $request->callback_query)
->onQueue('job')->through([RateLimited::middleware('job')]);
TestJob.php :
<?php
namespace App\Jobs\TestJob;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
class SendCallbackChat2desk implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable;
public function __construct($data, $params)
{
$this->data = $data;
$this->params = $params;
}
public function handle()
{
Log::info("JOB WORKING !!!");
//code ...
}
}
My middleware RateLimited:
<?php
namespace App\Jobs\Middleware;
use Illuminate\Cache\RateLimiter;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Cache\RateLimiting\Unlimited;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
class RateLimited
{
private RateLimiter $rateLimiter;
public function __construct(RateLimiter $rateLimiter)
{
$this->rateLimiter = $rateLimiter;
}
public static function middleware(string $name, bool $shouldSkipOnSync = false): string
{
return self::class . ':' . $name . ',' . ($shouldSkipOnSync ? 'true' : 'false');
}
public function handle($job, \Closure $next, string $name, string $shouldSkipOnSync)
{
if ($job->connection === 'sync' && $shouldSkipOnSync === 'true') {
return $next($job);
}
$releaseDelay = $this->calculateReleaseDelay($name, $job);
if ($releaseDelay > 0) {
return $job->release($releaseDelay);
}
return $next($job);
}
private function calculateReleaseDelay(string $name, $job): int
{
$limiters = Collection::make($this->resolvetRateLimit($name, $job))->filter();
$releaseDelay = $limiters->reduce(function (int $releaseDelay, Limit $limit) {
if ($limit instanceof Unlimited) {
return $releaseDelay;
}
if ($this->rateLimiter->tooManyAttempts($limit->key, $limit->maxAttempts)) {
return \max($this->limitWillBeAvaialableIn($limit), $releaseDelay);
}
return $releaseDelay;
}, 0);
if ($releaseDelay === 0) {
$limiters->each(function (Limit $limit) {
$this->rateLimiter->hit($limit->key, $limit->decayMinutes * 60);
});
}
return $releaseDelay;
}
private function resolvetRateLimit(string $name, $job): array
{
$callback = $this->rateLimiter->limiter($name);
if (\is_null($callback)) {
return [];
}
return Arr::wrap(\call_user_func($callback, $job));
}
private function limitWillBeAvaialableIn(Limit $limit): int
{
return ($this->rateLimiter->availableIn($limit->key) ?? 0) + 5;
}
}
AppServiceProvider:
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Cache\RateLimiter;
public function boot(RateLimiter $rateLimiter)
{
$rateLimiter->for('job', static function () {
return Limit::perMinute(1)->by('job');
});
}
queue.php:
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
'after_commit' => false,
],
QUEUE_CONNECTION=database
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|