我目前正在开发一个 Laravel 项目,该项目在单个作业中使用大型管道。在该管道内,会进行不同的第三方 API 调用,并将结果写入简单的 MariaDB 中。
功能上没有任何问题,一切都按预期工作。 但我不明白的是,如果作业在管道的某个点失败,它会很早就转移到“failed_jobs”表,尽管作业仍在后台进行,直到达到以下点:失败了。
有没有办法防止这种行为,或者这只是管道/队列组合的结果?这并没有让我太烦恼,但如果在每个开放步骤之后工作都被转移,那就更好了。
管道作业
class CompleteInboundLabelProcess implements ShouldQueue
{
use Queueable;
use InteractsWithQueue;
/**
* The number of times the job may be attempted.
*
* @var int
*/
public $tries = 1;
/**
* Indicate if the job should be marked as failed on timeout.
*
* @var bool
*/
public $failOnTimeout = true;
/**
* The number of seconds the job can run before timing out.
*
* @var int
*/
public $timeout = 900;
protected InboundShippingLabelContainer $container;
/**
* Create a new job instance.
*/
public function __construct(InboundShippingLabelContainer $container)
{
$this->container = $container;
}
/**
* Execute the job.
*/
public function handle(): void
{
try{
$filledContainer = app(Pipeline::class)
->send($this->container)
->through([
ListPrepDetailsPipeline::class,
SetPrepDetailsPipeline::class,
GetInboundOperationStatusPipeline::class,
ListPrepDetailsPipeline::class,
CreateInboundPlanPipeline::class,
GetInboundOperationStatusPipeline::class,
GeneratePackingOptionsPipeline::class,
GetInboundOperationStatusPipeline::class,
ListPackingOptionsPipeline::class,
ListPackingGroupItemsPipeline::class,
SelectPackingOptionPipeline::class,
ConfirmPackingOptionPipeline::class,
GetInboundOperationStatusPipeline::class,
SetPackingInformationPipeline::class,
GetInboundOperationStatusPipeline::class,
GeneratePlacementOptionsPipeline::class,
GetInboundOperationStatusPipeline::class,
ListPlacementOptionsPipeline::class,
GenerateTransportationOptionsPipeline::class,
ListTransportationOptionsPipeline::class,
SelectPlacementOptionPipeline::class,
ConfirmPlacementOptionPipeline::class,
GetInboundOperationStatusPipeline::class,
SelectTransportationOptionPipeline::class,
GetShipmentPipeline::class,
ConfirmTransportationOptionPipeline::class,
GetInboundOperationStatusPipeline::class,
GetShipmentPipeline::class,
ListShipmentBoxesPipeline::class,
GetLabelDownloadURLPipeline::class,
])
->then(function(InboundShippingLabelContainer $container){
$updateDB = InboundPlan::where('inboundplanid',$container->inboundPlanId)->where('account',$container->__get('account'))->update([
'shipmentid' => $container->confirmedshipmentid,
'confirmedplacementoptionid' => $container->confirmedplacementoptionid,
'confirmedpackingoptionid' => $container->confirmedpackingoptionid,
'confirmedtransportationoptionid' => $container->confirmedtransportationoptionid,
'labeldownloadurl' => $container->labeldownloadurl,
'packingoptions' => $container->packingoptions,
'placementoptions' => $container->placementoptions,
'shipment' => $container->shipment,
]);
return $container;
});
}catch(Exception $e){
if(boolval(env('APP_DEBUG'))){
DebugLog::create([
'function' => 'CompleteInboundLabelProcess',
'object' => json_encode($this->container,JSON_PRETTY_PRINT),
'message' => $e->getMessage()
]);
}
throw new \Exception($e->getMessage());
}
}
}
好吧..我找到了我的工作这么早就被调动的原因.. 它经常会因错误“maxAttemps[..]”而移动。
=> 虽然我将作业内的超时设置为 900 秒,但我的工作人员在默认时间后重试了作业。这会导致所描述的行为。工作完成了,但看起来已经失败了。
对我来说,解决方案是将工作线程超时参数设置为 0 秒(--timeout=0),这样我就可以在工作中选择超时,现在它按预期工作:)