РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
1358 of 1392 menu

Класс Job

Класс Job в Laravel - это абстракция, которая превращает обычный класс в задачу, которую можно отправить в очередь. Он определяет контракт для выполнения фоновой работы, предоставляя механизмы обработки, повторных попыток и обработки ошибок. В основе работы лежит метод handle, в котором пишется основная бизнес-логика. Класс также поддерживает атрибуты для настройки поведения: количество попыток, таймаут, задержка и другие. Использование Job позволяет перенести тяжёлые операции (отправка писем, работа с API, генерация отчётов) в фоновый режим, не блокируя работу веб-приложения.

Синтаксис

Для создания собственной задачи необходимо создать класс, который реализует интерфейс ShouldQueue. Обычно класс наследуется от базового абстрактного класса, но в Laravel принято использовать команду make:job, которая генерирует готовую заготовку. Основной метод, который должен быть определён в классе - это handle. Именно он вызывается при обработке задачи из очереди.

Пример

Создадим задачу для отправки уведомления пользователю после регистрации. Для этого сгенерируем класс через Artisan-команду и реализуем логику в методе handle:

<?php namespace AppJobs; use AppModelsUser; use IlluminateContractsQueueShouldQueue; use IlluminateFoundationBusDispatchable; use IlluminateQueueInteractsWithQueue; use IlluminateQueueSerializesModels; use IlluminateSupportFacadesLog; class SendWelcomeEmail implements ShouldQueue { use Dispatchable, InteractsWithQueue, SerializesModels; protected $user; public function __construct(User $user) { $this->user = $user; } public function handle() { // Логика отправки письма Log::info("Sending welcome email to: " . $this->user->email); // Здесь мог бы быть код отправки реального письма } } ?>

Теперь задачу можно поместить в очередь с помощью фасада dispatch. Это делается в любом месте приложения, например, в контроллере после регистрации пользователя:

<?php namespace AppHttpControllersAuth; use AppHttpControllersController; use AppJobsSendWelcomeEmail; use AppModelsUser; use IlluminateSupportFacadesHash; use IlluminateSupportFacadesLog; class RegisteredUserController extends Controller { public function store() { // Создание пользователя $user = User::create([ 'name' => 'John Doe', 'email' => 'john@example.com', 'password' => Hash::make('password'), ]); // Отправка задачи в очередь SendWelcomeEmail::dispatch($user); Log::info('User registered and job dispatched'); return response()->json(['message' => 'User registered']); } } ?>

Результат выполнения кода (логи):

"User registered and job dispatched" "Sending welcome email to: john@example.com"

Обратите внимание, что задача выполнится асинхронно, не задерживая ответ сервера.

Пример

Часто бывает необходимо указать количество попыток повторного выполнения задачи в случае сбоя. Для этого используется атрибут tries. Давайте создадим задачу, которая будет пытаться выполниться до 3 раз с интервалом 5 секунд между попытками:

<?php namespace AppJobs; use IlluminateContractsQueueShouldQueue; use IlluminateFoundationBusDispatchable; use IlluminateQueueInteractsWithQueue; use IlluminateQueueSerializesModels; use IlluminateSupportFacadesLog; class ProcessPayment implements ShouldQueue { use Dispatchable, InteractsWithQueue, SerializesModels; public $tries = 3; public $backoff = 5; public function handle() { Log::info('Processing payment...'); // Имитация ошибки для демонстрации throw new Exception('Payment gateway is temporarily unavailable'); } public function failed(Throwable $exception) { Log::error('Payment processing failed: ' . $exception->getMessage()); } } ?>

Теперь при выполнении задачи она будет повторно ставиться в очередь три раза с интервалом в 5 секунд. Если все попытки исчерпаны, будет вызван метод failed, где можно залогировать ошибку или уведомить администратора:

"Processing payment..." "Payment processing failed: Payment gateway is temporarily unavailable" "Processing payment..." "Payment processing failed: Payment gateway is temporarily unavailable" "Processing payment..." "Payment processing failed: Payment gateway is temporarily unavailable"

В реальном приложении в методе handle выполнялась бы логика взаимодействия с платёжным шлюзом, а повторные попытки помогли бы справиться с временными сетевыми проблемами.

Пример

Laravel позволяет использовать middleware прямо в классе задачи. Это полезно для настройки ограничений, например, чтобы задачи не перекрывали друг друга. Воспользуемся встроенным middleware WithoutOverlapping, чтобы гарантировать, что задача с одним и тем же ключом не выполняется одновременно:

<?php namespace AppJobs; use AppModelsUser; use IlluminateContractsQueueShouldQueue; use IlluminateFoundationBusDispatchable; use IlluminateQueueInteractsWithQueue; use IlluminateQueueSerializesModels; use IlluminateQueueMiddlewareWithoutOverlapping; use IlluminateSupportFacadesCache; use IlluminateSupportFacadesLog; class UpdateUserCache implements ShouldQueue { use Dispatchable, InteractsWithQueue, SerializesModels; protected $userId; public function __construct($userId) { $this->userId = $userId; } public function handle() { $user = User::find($this->userId); Cache::put('user_' . $this->userId, $user, 3600); Log::info('Cache updated for user: ' . $this->userId); } public function middleware() { return [ new WithoutOverlapping($this->userId) ]; } } ?>

Теперь если несколько задач UpdateUserCache для одного и того же пользователя будут поставлены в очередь, вторая из них не запустится, пока не завершится первая. Это предотвращает состояние гонки и избыточное обновление кеша:

"Cache updated for user: 1" "Cache updated for user: 2" // Для user 1 вторая задача будет ждать, пока освободится замок

Благодаря этому приёму можно безопасно работать с ресурсами, которые не поддерживают конкурентный доступ.

Смотрите также

  • метод handle,
    основной метод, содержащий логику задачи
  • метод failed,
    вызывается при неудачном завершении задачи после исчерпания попыток
  • атрибут tries,
    определяет максимальное количество попыток выполнения задачи
  • атрибут backoff,
    задаёт задержку между повторными попытками задачи
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить