Класс Batch
Класс Batch предоставляет возможность группировать несколько заданий в единый пакет (batch) и управлять ими как единым целым. Это особенно полезно при выполнении большого количества связанных задач, когда необходимо отслеживать общий прогресс, обрабатывать ошибки и выполнять завершающие действия после окончания всех заданий. Объект Batch возвращается методом batch фасада Bus при создании пакета.
Основные методы класса позволяют регистрировать коллбэки на успешное выполнение всех заданий (then), на возникновение ошибки в одном из заданий (catch), а также выполнять код в любом случае (finally). Кроме того, доступны методы для получения информации о прогрессе, отмены пакета и настройки обработки ошибок.
Создание пакета заданий
<?php
use AppJobsProcessOrder;
use AppJobsUpdateInventory;
use AppJobsSendOrderEmail;
use IlluminateSupportFacadesBus;
$batch = Bus::batch([
new ProcessOrder($orderId),
new UpdateInventory($orderId),
new SendOrderEmail($orderId),
])->dispatch();
?>
Метод then - коллбэк при успешном завершении
Метод then принимает замыкание, которое будет выполнено после успешного завершения всех заданий в пакете. Замыкание получает экземпляр класса Batch в качестве аргумента.
<?php
use AppJobsProcessOrder;
use AppJobsUpdateInventory;
use AppJobsSendOrderEmail;
use IlluminateSupportFacadesBus;
use IlluminateSupportFacadesLog;
$batch = Bus::batch([
new ProcessOrder($orderId),
new UpdateInventory($orderId),
new SendOrderEmail($orderId),
])->then(function (Batch $batch) {
Log::info('All jobs completed successfully', ['id' => $batch->id]);
})->dispatch();
?>
Метод catch - коллбэк при ошибке
Метод catch определяет замыкание, которое выполняется при возникновении ошибки в любом из заданий пакета. Замыкание получает экземпляр Batch и перехваченное исключение в качестве аргументов.
<?php
use AppJobsProcessOrder;
use AppJobsUpdateInventory;
use AppJobsSendOrderEmail;
use IlluminateSupportFacadesBus;
use IlluminateSupportFacadesLog;
$batch = Bus::batch([
new ProcessOrder($orderId),
new UpdateInventory($orderId),
new SendOrderEmail($orderId),
])->catch(function (Batch $batch, Throwable $e) {
Log::error('Batch failed', ['id' => $batch->id, 'error' => $e->getMessage()]);
})->dispatch();
?>
Метод finally - коллбэк в любом случае
Метод finally регистрирует замыкание, которое будет выполнено независимо от того, завершился пакет успешно или с ошибкой. Это полезно для освобождения ресурсов или выполнения завершающих действий.
<?php
use AppJobsProcessOrder;
use AppJobsUpdateInventory;
use AppJobsSendOrderEmail;
use IlluminateSupportFacadesBus;
use IlluminateSupportFacadesLog;
$batch = Bus::batch([
new ProcessOrder($orderId),
new UpdateInventory($orderId),
new SendOrderEmail($orderId),
])->finally(function (Batch $batch) {
Log::info('Batch finished processing', ['id' => $batch->id]);
})->dispatch();
?>
Метод progress - получение прогресса
Метод progress возвращает процент выполнения пакета в виде целого числа от 0 до 100. Это удобно для отображения прогресса пользователю.
<?php
use IlluminateSupportFacadesBus;
$batch = Bus::batch([
// jobs
])->dispatch();
$progress = $batch->progress();
echo "Progress: " . $progress . "%";
?>
Результат выполнения кода:
"Progress: 45%"
Метод cancel - отмена пакета
Метод cancel отменяет выполнение всех ещё не запущенных заданий в пакете. Уже выполняющиеся задания продолжат работу, но новые не будут запущены.
<?php
use IlluminateSupportFacadesBus;
$batch = Bus::batch([
// jobs
])->dispatch();
$batch->cancel();
?>
Метод allowFailures - разрешение ошибок
Метод allowFailures позволяет настроить пакет так, чтобы при ошибке в одном задании остальные продолжали выполняться. По умолчанию пакет останавливается при первой ошибке.
<?php
use AppJobsProcessOrder;
use AppJobsUpdateInventory;
use AppJobsSendOrderEmail;
use IlluminateSupportFacadesBus;
$batch = Bus::batch([
new ProcessOrder($orderId),
new UpdateInventory($orderId),
new SendOrderEmail($orderId),
])->allowFailures()->dispatch();
?>
Метод name - задание имени пакета
Метод name позволяет задать понятное имя для пакета, которое будет полезно при отладке и логировании.
<?php
use AppJobsProcessOrder;
use AppJobsUpdateInventory;
use AppJobsSendOrderEmail;
use IlluminateSupportFacadesBus;
use IlluminateSupportFacadesLog;
$batch = Bus::batch([
new ProcessOrder($orderId),
new UpdateInventory($orderId),
new SendOrderEmail($orderId),
])->name('Order Processing Batch')->then(function (Batch $batch) {
Log::info('Batch completed', ['name' => $batch->name]);
})->dispatch();
?>
Пример комплексного использования
Рассмотрим пример полного цикла работы с пакетом заданий: создание, обработка успеха, ошибок и получение информации о пакете.
<?php
use AppJobsProcessOrder;
use AppJobsUpdateInventory;
use AppJobsSendOrderEmail;
use AppJobsGenerateInvoice;
use IlluminateSupportFacadesBus;
use IlluminateSupportFacadesLog;
use IlluminateSupportFacadesCache;
$batch = Bus::batch([
new ProcessOrder($orderId),
new UpdateInventory($orderId),
new SendOrderEmail($orderId),
new GenerateInvoice($orderId),
])->name('Order Full Processing')
->allowFailures()
->then(function (Batch $batch) {
Cache::put('batch_' . $batch->id . '_status', 'completed');
Log::info('All jobs done', ['id' => $batch->id, 'name' => $batch->name]);
})
->catch(function (Batch $batch, Throwable $e) {
Cache::put('batch_' . $batch->id . '_status', 'failed');
Log::error('Error in batch', ['id' => $batch->id, 'error' => $e->getMessage()]);
})
->finally(function (Batch $batch) {
Log::info('Batch finished with progress ' . $batch->progress() . '%');
})
->dispatch();
?>
После выполнения пакета можно получить информацию о нём:
<?php
use IlluminateSupportFacadesBus;
$batch = Bus::findBatch($batchId);
if ($batch) {
echo "Batch ID: " . $batch->id;
echo "Name: " . $batch->name;
echo "Progress: " . $batch->progress() . "%";
echo "Status: " . ($batch->finished() ? 'finished' : 'processing');
}
?>
Результат выполнения кода:
"Batch ID: 12345"
"Name: Order Full Processing"
"Progress: 100%"
"Status: finished"
Смотрите также
-
метод
Bus::batch,
который создаёт новый пакет заданий -
метод
then,
который определяет коллбэк при успехе -
метод
catch,
который обрабатывает ошибки пакета -
метод
cancel,
который отменяет выполнение пакета