#laravel
Вопрос:
У меня есть задание, как показано ниже:
class ProcessActions implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
protected $user_id;
public $uniqueFor = 4;
/**
* Create a new job instance.
*
* @param mixed $action_id
*/
public function __construct($user_id)
{
$this->user_id = $user_id;
}
public function uniqueId()
{
return $this->user_id;
}
/**
* Handle a job failure.
*/
public function failed()
{
}
/**
* Execute the job.
*/
public function handle()
{
Log::debug('');
Log::debug('Started Time: '.date('Y-m-d H:i:s'));
try {
} catch (Exception $e) {
Log::critical('Error occurred.');
Log::critical($e);
// make the job failed
$this->job->fail($e);
}
}
public function middleware()
{
return [(new WithoutOverlapping($this->user_id))->releaseAfter(4)->expireAfter(4)];
}
}
Как я должен предотвратить одновременное выполнение заданий? уникальные и без перекрытия не сработали, и у меня есть задания, которые выполняются одновременно.
На самом деле я хочу, чтобы задания с одинаковым идентификатором пользователя выполнялись с задержкой в 4 секунды.
Кроме того, поскольку я проверил jobs’available_at и время, когда я вошел в дескриптор, имеют разницу в несколько секунд.
Комментарии:
1. возможно, вы можете использовать sleep (5) в конце каждого задания с задержкой в 5 секунд
2. Вы можете подумать github.com/spatie/laravel-rate-limited-job-middleware .
Ответ №1:
Вы можете использовать функцию ограничения скорости в laravel
Подробнее об этом можно прочитать здесь — https://laravel.com/docs/8.x/queues#rate-limiting —
В вашем классе заданий внутри метода дескриптора добавьте этот код — убедитесь key
, что это уникальное значение, вот пример кода
По сути, это ограничивает работника обработкой одного задания для пользователя в данный момент времени.смотрите uuid, следующее задание будет обработано через 4 секунды.
$uuid='process_action_'.$user_id;
Redis::funnel($uuid)->limit(1)->then(function () {
//job logic
}, function () {
//reattempt the job after 4 seconds
return $this->release(4);
});