3

I'm writing an app on Silex in accordance with the documentation but with some additions. I declare the route, after middleware for route and finish middleware for app.

$app->put('/request/', function (Request $request) use ($app) {
    // ... some code here ...

    return $app->json(['requestId' => $requestId], 201);
})->bind('create_request')
->after(function(Request $request, Response $response) {
    $contentLength = mb_strlen($response->getContent(), 'utf-8');
    $response->headers->set('Content-length', $contentLength, true);
    $response->headers->set('Connection', 'close', true);
});

$app->finish(function (Request $request, Response $response, Application $app) {
    flush();

    // ... generate big pdf file, attach it to email and send via swiftmailer ...
});

The above code works as I need: response is sended, browser spinner is stopped, heavy operation is processed in background. But there is an open question: is it necessary to add headers to the response in after middleware and flush buffer in finish middleware? Without these manipulations server response is received only after the completion of finish middleware handler.

Max P.
  • 5,579
  • 2
  • 13
  • 32
IvanMalenko
  • 427
  • 2
  • 13
  • Would you please kindly shed more light on this Q&A, as I am exactly on the same thing. It would be helpful if you could put some time to add some more explanation to your question and provide a more detailed answer. Tnx in advance. For example how could you detect what is the source data for the pdf, as finish is fired on ALL routes – Peyman Mohamadpour Jan 10 '17 at 21:07
  • @Trix If I understand you correctly, you need to notify the browser about a new pdf file. You can use WebSocket for this purposes. This way you will not need to directly monitor the result of the finish middleware handler. – IvanMalenko Jan 12 '17 at 15:42
  • @Trix My task was as follows: save user input, generate pdf report based on it and send a letter with this report. After processing user input i'm send a response to browser and close connection ("after" section). In the "finish" section i'm processing $response object, generate file and send a letter (no notifications to browser here). – IvanMalenko Jan 12 '17 at 15:53
  • Tnx for ur response, [this](http://stackoverflow.com/questions/41562964/silex-get-right-condionals-in-finish-middleware) is what I am after – Peyman Mohamadpour Jan 12 '17 at 16:50

1 Answers1

1

I think that it is necessary.
->after( is RESPONSE event that is called when response is prepared, but not sent. In your case all necessary headers to close connection when browser receives response are added.
->finish( is TERMINATE event that is called after response was sent. flush() - I think that it used to flush response from server buffer to browser.

Max P.
  • 5,579
  • 2
  • 13
  • 32
  • But the "TERMINATE" event occurs after sending a response to the browser and all caches are cleared by fastcgi_finish_request/ob_end_flush/ob_end_clean (nothing to send after that) and only then "finish" middleware handler invoked. Am I missing something? – IvanMalenko Jun 04 '16 at 20:37
  • `fastcgi_finish_request ` - it is php-fpm function. Do you use php-fpm? – Max P. Jun 04 '16 at 20:52
  • No, I just listed a set of possible functions. One of them called, after sending the response (in Symfony\Component\HttpFoundation\Response). – IvanMalenko Jun 04 '16 at 20:58
  • I've looked too. `ob_..` functions work with buffer on script level, so after `ob_end_flush` php sends output buffer to system. Than `flush()` flush system output buffer (http://php.net/manual/en/function.flush.php). It is only my suppose.. – Max P. Jun 04 '16 at 21:11