Здравствуй, %username%.
В L5
(как и в предыдущих версиях) есть замечательный
schedule-ер, который позволяет запускать задачи
(оформленные как команды для artisan) по расписанию, и на шаге инициализации задачи мы можем юзать замечательный "флаг"
->withoutOverlapping()
, который предотвращает запуск команды, если она ещё не завершена, например:
$schedule
->command('queue:listen')
->everyMinute()
->withoutOverlapping();
А так же есть ещё более замечательная штука, как
Queue (и реализация самих задач под названием Job
). Так вот, возник вопрос - как обеспечить гарантию того, что один и тот же
Job
не будет запущен дважды в одну единицу времени? Так как операция запускается длительная в нем, существует вероятность что она будет выполнена дважды. Контекст её вызова пока не важен. Я сделал следующим образом:
// /app/Jobs/Job.php
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class Job implements ShouldQueue {
use InteractsWithQueue,
Queueable,
SerializesModels;
/**
* Get path to the 'lock' file.
*
* @return string
*/
protected function getLockFilePath() {
return storage_path('framework/schedule-' . md5(__NAMESPACE__ . get_class($this)) . '.lock');
}
/**
* Lock current job (PREVENTING OVERLAPPING).
*
* @return boolean
*/
protected function lock() {
return touch($this->getLockFilePath());
}
/**
* Disable locking.
*
* @return boolean
*/
protected function unlock() {
return unlink($this->getLockFilePath());
}
/**
* Check - job is locked?
*
* @return boolean
*/
protected function locked() {
return file_exists($this->getLockFilePath());
}
}
После чего наследую данный класс, и юзаю примерно так:
// /app/Jobs/SomeJob.php
<?php
namespace App\Jobs;
use App\Jobs\Job;
class SomeJob extends Job {
/**
* Execute the job.
*
* @return void
*/
public function handle() {
// PREVENTING OVERLAPPING
if (!$this->locked()) {
$this->lock();
// LONG-LONG operation is here
$this->unlock();
}
}
}
И вот вопрос - на сколько этот метод колхозный? Может я упустил что-то в документации к Ларке?