'Laravel whole batch is cancelled if one Job fails
I'm working on a Laravel project that uses the Batching feature to batch a bunch of Jobs into a Batch. In my context, I have around 50 jobs in a batch, each job has a max tries of 3, if one job out of the 50 fails due to it exceeding the maximum retries then the entire batch is cancelled, I don't want this as the other 49 jobs may very well succeed, how can I prevent the batch from failing unless all jobs fail in a batch?
My existing functionality takes a CSV, chunks the CSV into smaller ones and then each smaller one is it's own job to process as part of a batch...
/**
* Create chunked CSVs
*/
protected function createChunkedCSVs($schedule)
{
$this->updateSchedule($schedule->id, 'generating_batches');
try {
// get the CSV we stored
$storagePath = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix();
$data = file($storagePath . $schedule->csv_path);
// get file name
$name = $schedule->csv_name;
$batchName = $name;
// chunk the CSV into small jobs of 150 customers per Job
// so that they can be inserted quicker (originally 1,000)
$chunks = array_chunk($data, 150);
// header and batch
$header = [];
$batch = Bus::batch([])->name("Customer Import ($batchName)")->dispatch();
// begin chunking
foreach ($chunks as $key => $chunk) {
$data = array_map('str_getcsv', $chunk);
if ($key === 0) {
$header = $data[0];
unset($data[0]);
// validate headers exist
$isValid = $this->validateHeadersExist($batch, $header, $schedule);
if ((isset($isValid) && !empty($isValid)) && $isValid == 'cancel') {
return;
}
}
$batch->add(new CustomersCsvProcess($name, $data, $header));
}
if (!$batch) {
$this->updateSchedule($schedule->id, 'error');
}
$this->setBatch($schedule->id, $batch->id);
$this->updateSchedule($schedule->id, 'processing_jobs');
} catch (\Exception $e) {
$this->updateSchedule($schedule->id, 'error');
}
// clean storage directory
try {
Artisan::call('csv:storage:clear --hours=0.25');
} catch (\Exception $e) { }
// update schedules
try {
Artisan::call('csv:update:finished');
} catch (\Exception $e) { }
}
Solution 1:[1]
You probably already solve it, but..
You need to add allowFailures() to the batch
$batch = Bus::batch([])->name("Customer Import ($batchName)")->allowFailures()->dispatch();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Fabi Curti |