Send HTTP response and continue processing PHP

peterpp
Member | 9
+
0
-

I would like to continue processing PHP and finish a longer job after HTTP response is sent. I'm not sure, how to terminate a Nette Presenter properly. Right now, I have this code:

public function actionLongTask(): void
{
    $this->flashMessage("I will continue in background.");

    // Prepare redirect response to finish the action on client side.
    $response = new RedirectResponse($this->link("default"));

    // Shut down the presenter - this code is taken from Presenter.run() method.
    $this->saveGlobalState();
    if ($this->hasFlashSession()) {
        $this->getFlashSession()->setExpiration('30 seconds');
    }
    Arrays::invoke($this->onShutdown, $this, $response);
    $this->shutdown($response);

    // Send HTTP response and flush all buffers.
    // https://stackoverflow.com/questions/15273570/continue-processing-php-after-sending-http-response
    ignore_user_abort(true);
    set_time_limit(0);

    ob_start();
    $this->getHttpResponse()->addHeader("Connection", "close");
    $response->send($this->getHttpRequest(), $this->getHttpResponse());
    $this->getSession()->close();
    ob_end_flush();
    @ob_flush();
    flush();

    // Do some stuff (call API, write to database, etc.).
    sleep(5);
    Debugger::log("Background task finished");
}

This works almost fine but there are two problems:

  1. Next request to the server is blocked until the first one is finished. I assume there is some file lock (session, logs) that is blocking the second request, but I really don't know.
  2. Flesh message “I will continue in background.” is not shown.

Any ideas how to fix it?

dkorpar
Member | 136
+
0
-

This should be executed in different process… You need either some queue, or cron processing, even executing php script as background process could potentially work…

peterpp
Member | 9
+
0
-

I finally used exec() command like this:

exec("php $scriptPath $parameter &> /dev/null &");

The advantage is that it is executed immediatelly, unlike cron processing.