Laravel批量任务失败后添加新任务无法执行求助
Laravel批量任务停滞:失败后添加的任务无法执行
问题背景
我尝试了多种方法仍无法解决该问题,且确认最近一次框架更新前功能完全正常(对比源码未找到相关线索)。
需求
当批量中的StartTestJob耗尽重试次数失败后,向该批量中添加并执行FindNextSiteTestJob,此任务负责查找未处理的站点,并向批量中添加新的StartTestJob。
环境说明
- 后台Worker持续运行(通过
pgrep监控) - 使用
mateusjunges/trackable-jobs-for-laravel包跟踪批量任务 - 采用数据库驱动队列
- 代码修改后会执行
php artisan queue:restart
当前问题
FindNextSiteTestJob已被正确加入批量,但整个批量被标记为失败,该任务一直处于排队状态,批量执行完全停滞。
启动批量任务代码
$server = Server::find($server_id); $sites = $server->sites->all(); $max_simultaneous_procs = $server->simultaneous_procs; $batchJobs = []; $batch_reference_uuid = (string) Str::orderedUuid(); $sites = array_slice($sites, 0, $max_simultaneous_procs); foreach ($sites as $site) { $chain_uuid = (string) Str::orderedUuid(); $batchJobs [] = [new StartTestJob($site, $chain_uuid, $batch_reference_uuid)]; } /********************** // 分发批量任务 **********************/ $queue_name = 'procs_test_server_' . $server_id; $batch_name = 'server-'. $server_id . ' : TestBatchSimultaneous' . ' ' . Carbon::now()->format('Y-m-d H:i'); $log_path = 'uuuuuu/storage/logs/jobs.log'; try { $batch = Bus::batch( $batchJobs )->then(...)->catch(...)->finally(...) ->onQueue($queue_name)->name($batch_name)->withOption("reference_uuid", $batch_reference_uuid)->dispatch(); // ->allowFailures() 没有任何效果 }
队列停滞状态
StartTestJob执行失败后,FindNextSiteTestJob进入队列但永远不会被执行。
相关任务代码
StartTestJob
class StartTestJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, Batchable, ChainedTrackable { __construct as __baseConstruct; } public $site; public $chain_uuid; public $batch_reference_uuid; public function __construct(Site $site, string $chain_uuid, string $batch_reference_uuid) { $this->__baseConstruct($site, $chain_uuid, $batch_reference_uuid); $this->site = $site; $this->chain_uuid = $chain_uuid; $this->batch_reference_uuid = $batch_reference_uuid; } public function handle() { // 测试环境中此处查询结果永远为空 $pingback_happened = Pingback::where(['chain_uuid' => $this->chain_uuid])->first(); if(!$pingback_happened ){ $this->release(5); return; } } public function retryUntil(){ return now()->addSeconds(15);} public function failed($exception) { new FindNextSiteTestJob($this->site, $this->chain_uuid, $this->batch_reference_uuid); } }
FindNextSiteTestJob
class FindNextSiteTestJob implements ShouldQueue, ShouldBeUnique { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, Batchable, ChainedTrackable { __construct as __baseConstruct; } public $site; public $chain_uuid; public $batch_reference_uuid; public function __construct(Site $site, string $chain_uuid, string $batch_reference_uuid) { $this->__baseConstruct($site, $chain_uuid, $batch_reference_uuid); $this->site = $site; $this->chain_uuid = $chain_uuid; $this->batch_reference_uuid = $batch_reference_uuid; } public function handle() { $batch_reference_uuid = $this->batch_reference_uuid; // 查找一个尚未处理的站点 $sites_done = \Illuminate\Support\Facades\DB::table('tracked_jobs')->select('trackable_id')->where('batch_reference_uuid', $batch_reference_uuid)->groupBy('trackable_id')->get()->pluck('trackable_id')->toArray(); $server = Server::find($this->site->server_id); $site_left = $server->sites->whereNotIn('id', $sites_done)->first(); if($site_left){ $site = $site_left; $chain_uuid = (string) Str::orderedUuid(); $jobChain = [ new StartTestJob($site, $chain_uuid, $batch_reference_uuid), ]; $this->batch()->fresh()->add($jobChain); // 即使改用dispatch()也无效: //$this->batch()->fresh()->add($jobChain)->dispatch(); } } public function failed($exception){} }
内容的提问来源于stack exchange,提问作者urka_mazurka
相关产品推荐
相关产品推荐

