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 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog