You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel获取失败任务ID以关联请求重新提交的技术问题

嘿,我来帮你搞定这个问题!看起来你已经走了大半路程,只差把失败任务的ID和你的构建请求关联起来,然后实现重新提交功能了。我分步骤给你讲清楚:

第一步:在failed()方法中获取failed_jobs表的记录ID

Laravel默认会把失败任务存入failed_jobs表,但任务的failed()方法本身不会直接返回这个表的自增ID。不过我们可以通过任务的UUID(队列任务的唯一标识)去查询这条记录:

public function failed($exception)
{
    // 获取当前失败任务的UUID
    $jobUuid = $this->job->uuid();
    
    // 从failed_jobs表中查询对应的记录
    $failedJob = \Illuminate\Support\Facades\DB::table('failed_jobs')
        ->where('uuid', $jobUuid)
        ->first();
    
    if ($failedJob) {
        // 这里假设你的构建请求表有个字段叫failed_job_id,用来关联失败任务ID
        // 记得提前在构建请求表中添加这个字段哦
        $this->linkFailedJobToBuildRequest($failedJob->id);
    }
}

// 辅助方法:关联构建请求与失败任务ID
private function linkFailedJobToBuildRequest($failedJobId)
{
    // 假设你的任务类里有buildRequestId属性,用来关联对应的构建请求
    \App\Models\BuildRequest::where('id', $this->buildRequestId)
        ->update(['failed_job_id' => $failedJobId]);
}

第二步:在表格中添加重新提交按钮

现在你的构建请求已经和failed_jobs表的ID关联上了,接下来在表格里给失败的任务加按钮就行。假设你用Blade模板渲染表格:

@foreach($buildRequests as $request)
<tr>
    <td>{{ $request->server_name }}</td>
    <td>{{ $request->status }}</td>
    <td>
        @if($request->status === 'failed' && $request->failed_job_id)
            <form action="{{ route('retry.failed.job', $request->failed_job_id) }}" method="POST">
                @csrf
                <button type="submit" class="btn btn-sm btn-primary">重新提交任务</button>
            </form>
        @endif
    </td>
</tr>
@endforeach

第三步:实现重新提交的逻辑

最后写个控制器方法,调用Laravel自带的队列重试命令来重新提交失败任务:

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Artisan;
use Illuminate\Http\Request;

class BuildController extends Controller
{
    public function retryFailedJob($failedJobId)
    {
        // 调用Artisan命令重试指定ID的失败任务
        Artisan::call('queue:retry', ['id' => $failedJobId]);
        
        // 跳转回表格页面并提示成功
        return redirect()->back()->with('success', '任务已重新提交,等待执行!');
    }
}

别忘了在路由文件里注册这个路由:

Route::post('/build/retry/{failedJobId}', [BuildController::class, 'retryFailedJob'])->name('retry.failed.job');

额外优化:用事件监听批量处理关联

如果你有多个任务类型,或者不想在每个任务的failed()方法里写重复代码,可以用Laravel的事件监听:

  1. 生成监听器:
php artisan make:listener JobFailedListener --event=Illuminate\Queue\Events\JobFailed
  1. 在监听器里处理关联逻辑:
public function handle(\Illuminate\Queue\Events\JobFailed $event)
{
    $jobUuid = $event->job->uuid();
    $failedJob = \DB::table('failed_jobs')->where('uuid', $jobUuid)->first();
    
    if ($failedJob) {
        // 解析任务 payload,拿到构建请求ID(根据你的任务结构调整)
        $payload = json_decode($event->job->getRawBody(), true);
        $buildRequestId = $payload['data']['command']->buildRequestId;
        
        // 更新构建请求表
        \App\Models\BuildRequest::where('id', $buildRequestId)
            ->update(['failed_job_id' => $failedJob->id]);
    }
}
  1. 在EventServiceProvider里注册监听器:
protected $listen = [
    \Illuminate\Queue\Events\JobFailed::class => [
        \App\Listeners\JobFailedListener::class,
    ],
];

这样不管哪个任务失败,都会自动关联到对应的构建请求,不用在每个任务里写重复代码啦~

内容的提问来源于stack exchange,提问作者debow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:09:14