-
-
Save farconada/d59445416bafd6a73b27 to your computer and use it in GitHub Desktop.
As a way to integrate microservices I want to use HTTP calls and avoid the use of a MQ (Message Queue). | |
If the app is small and contained in one host you could avoid the use of MQ. | |
Description of the scenario: | |
I have one app (made with Symfony. Call it MainApp) and one microservice (made with Sylex. Call MicroApp), both served using PHP-FPM NGINX | |
1) MainApp calls an URL POST /api/internal/do-something with Guzzle, | |
2) then MicroAPP do its work (it takes long) | |
3) MicroApp calls an URL from /api/internal/i-have-finished | |
To avoid keep MainApp waiting in 1). I've configured a very small guzzle timeout and it catches the exception. With this trick I have an Async HTTP call. | |
Are there any way to 2) in background without a MQ (and without anykind of worker proccess). | |
I'm tempted to use threads for 2) but I've read that they are only suitable for CLI (https://github.com/krakjoe/pthreads). | |
I've heard that Spring have async REST. | |
What's the best way to solve this scenario and avoid waiting for 2) ? |
sorry It uses 0mq
Sorry, that article wasn't that relevant, the top "notice" of the page was. Can't you use the kernel.terminate
event to perform the long-running code? See http://symfony.com/doc/current/components/http_kernel/introduction.html#the-kernel-terminate-event for more information.
For a Silex specific example, see http://gonzalo123.com/2013/10/14/using-the-event-dispatcher-in-a-silex-application/
It might not work for you though because of this limitation:
Internally, the HttpKernel makes use of the
fastcgi_finish_request
PHP function. This means that at the moment, only the PHP FPM server API is able to send a response to the client while the server's PHP process still performs some tasks. With all other server APIs, listeners tokernel.terminate
are still executed, but the response is not sent to the client until they are all completed
@farconada as @grEvenX commented, you can either implement your code as a listener to the kernel.terminate
event or you can manually call fastcgi_finish_request
on the controller and after that point you can execute whatever logic you need in the background.
You'll need to make sure to set any headers on the response and set the content, before calling fastcgi_finish_request().
I don't have an example on Silex, but I'm using this on an App with an internal framework.
this solution seems ok but only works with php-fpm I'll try it in a few minutes. thanks
Dont you think that it will be a better solution with with threads? (pthreads are only available in CLI)
Silex after() isn't the solution but $app->finish() do the work pretty well
Is this a possible solution on #2 for you: http://davedevelopment.co.uk/2011/12/02/handling-symfony-events-asynchronously.html (closing the request early, leveraging the event-system to continue processing data after it is closed)