Как задание Laravel в очереди обрабатывает удаленную модель как ввод?
Что произойдет, если задание Laravel в очереди передается модели Eloquent в качестве входных данных, но модель удаляется до запуска задания в очереди?
Например, я создаю сайт электронной коммерции с Laravel 5.2, где клиент может вводить адреса и способы оплаты. Способ оплаты принадлежит адресу. Но если клиент пытается удалить адрес, а не каскадно и не удаляет любые способы оплаты, связанные с ним, я мягко удаляю адрес, помечая его как отключенный. Таким образом, способ оплаты может использоваться до тех пор, пока клиент не обновит адрес выставления счета, связанный с ним.
Однако, если метод оплаты удален и он ссылается на адрес, который был удален программным способом, я хочу выполнить сборку мусора и удалить адрес из базы данных. Это не должно происходить синхронно, поэтому я написал простую очередь для достижения этой цели. Метод handle выглядит следующим образом:
public function handle(PaymentMethodRepository $paymentMethodRepository, AddressRepository $addressRepository)
{
$billingAddress = $paymentMethodRepository->address($this->paymentMethod);
if ( ! $billingAddress->enabled) {
$addressRepository->delete($billingAddress);
}
}
Я отправляю эту работу в destroy
метод PaymentMethodsController. Однако если способ оплаты, переданный заданию, будет удален из базы данных до того, как задание будет выполнено в очереди, произойдет ли сбой задания?
Я все еще разрабатываю сайт, поэтому у меня нет сервера для развертывания и тестирования того, что происходит. Я знаю, что модель сериализуется для помещения в очередь, но мне интересно, возникнет ли проблема при восстановлении модели для выполнения задания.
1 ответ
Да, задание не будет выполнено, если "сериализованная модель" будет удалена перед выполнением задания. Модель на самом деле не сериализована - задание сохраняет класс модели и идентификатор модели и извлекает модель перед выполнением.
Чтобы обойти это, вы можете сохранить первичный ключ модели в задании, а затем при выполнении задания проверить, существует ли запись:
class DeleteAddressJob extends Job implements ShouldQueue
{
private $addressId;
public function __construct(int $addressId)
{
$this->addressId = $addressId;
}
public function handle(AddressRepository $addressRepository)
{
$address = $addressRepository->find($this->addressId);
if (is_null($address)) {
// Address doesn't exist. Complete job...
return;
}
// Delete the address...
}
}