dragam0217 2017-10-25 22:28
浏览 380
已采纳

发送响应但保持长时间运行的脚本以防止超时?

I am wondering how to deal with this. I have a webhook endpoint which responds to a webhook call from Github.

It starts a long running process in where it clones the repository from which the webhook call was made.

/**
* The webhook endpoint.
*
* @param Request $request
* @return mixed
* @throws \Exception
*/
public function webhook(Request $request)
{
    // The type of GitHub event that we receive.
    $event = $request->header('X-GitHub-Event');

    $url = $this->createCloneUrl();
    $this->cloneGitRepo($url);

    return new Response('Webhook received succesfully', 200);
}

The problem with this is that Github gives an error when the response is not provided soon enough.

We couldn’t deliver this payload: Service Timeout

This is rightfully so because my cloneGitRepo method is simply blocking the execution of the response and it is taking too long.

How can I still deliver a response to acknowledge to Github that the webhook call has been made successfully and start my long running process?

I am using Laravel for all of this with Redis, maybe something can be accomplished there? I am open to all suggestions.

  • 写回答

1条回答 默认 最新

  • dongshang6790 2017-10-26 17:03
    关注

    What you're looking for is a queued job. Laravel makes this very easy with Laravel Queues.

    With queues, you setup a queue driver (database, redis, Amazon SQS, etc), and then you have one to many queue workers that are continuously running. When you put a job on the queue from your webhook method, it will be picked up by one of your queue workers and run in a separate process. The act of dispatching a queued job to a queue is very quick, though, so your webhook method will return quickly while the real work is being done by the queue worker.

    The linked documentation has all the details, but the general process will be:

    1. Setup a queue connection. You mention you're already using redis, I would start with that.

    2. Use php artisan make:job CloneGitRepo to create a CloneGitRepo job class.

      • It should implement the Illuminate\Contracts\Queue\ShouldQueue interface so that Laravel knows to send this job to a queue when it is dispatched.

      • Make sure to define properties on the class for any data you pass into the constructor. This is necessary so the worker can rebuild the job correctly when it is pulled off the queue.

      • The queue worker will call the handle() method to process the job. Any dependencies can be type hinted here and they will be injected from the IoC container.

    3. To dispatch the job to the queue, you can either use the global dispatch() helper function, or call the static dispatch() method on the job itself.

      • dispatch(new CloneGitRepo($url));

      • CloneGitRepo::dispatch($url);

    So, your webhook would look like:

    public function webhook(Request $request)
    {
        // The type of GitHub event that we receive.
        $event = $request->header('X-GitHub-Event');
    
        $url = $this->createCloneUrl();
    
        CloneGitRepo::dispatch($url);
    
        return new Response('Webhook received succesfully', 200);
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作