I would like to share a rapid test on making parallel HTTP requests with PHP. For our needs in the Integrations swarm at iAdvize, we have to make multiple HTTP requests within a synchronous one.
We provide a standard way to use some pieces of our UI, so connectors can subscribe to them by configuring an URI we will call to retrieve data and display them the same way for each connector. Connector data must conform to our JSON-SCHEMA, each data type has his own schema.
Some of these plugins use one connector, for example our front UI make a call to get all client products from the connector shopify. Others aggregate all data from different installed connectors. In this case we make one HTTP request from our UI to our connectors domain API which call all connectors URIs. Actually this is done in a sequential way like this
We are controlling external connector system so we cannot guarantee a response time. We set a timeout for connector to respond, but we still have “the more connectors are installed, the more time the request takes”. In this case we wanted to parallelize HTTP request to answer faster…obviously. So i quickly test some asynchronous way to do that. Asynchronous is trendy in PHP these times but i wanted to test it concretely as it is quite new to me.
You can find a console application here to test the 3 methods. Default URI is set to https://httpstat.us/200?sleep=1500, this service let you set request time and status code. Be careful when testing other URIs, use server that can than can handle many simultaneous requests to limit server side effects on the test (php local server is bad idea for example as it can only manage one simultaneous request).
I have made 2 tests with a number of 5 & 10 requests. These test call an URI that return a 200 status code and each server responds in 1,5 seconds (https://httpstat.us/200?sleep=1500). Look at httpstat.us for different response time & status.
There is no significant difference between Guzzle Async and AMP. We can see a clear difference, oh what a surprise, between sync & async. Both async methods take the same time to execute 5 or 10 requests of 1,5 seconds, so it’s a good answer for our problem.
We already use Guzzle in production so we will use this one as we know it better. Both Guzzle and AMP come with classic promises tools, helping you with your requests management. Like all requests must succeed, some of them, first of them… You can find ways to manage number of “concurrent jobs” with Guzzle Pool and with AMP semaphore (a lock system).
I would recommend to use Guzzle if you only want to parallelize http requests. If you have other type of actions to perform in parallel look after AMP that let you manage more different I/O types like database connections, http requests... I haven’t explore PHP multi threading / processes that is documented in Amp parallel, it’s a more complex question and that wasn’t the subject of my test.
Go further with concurrency & asynchrone in PHP
Concurrent HTTP requests without opening too many connections - madewithlove
We help companies build digital products and bring new juice to teams that seem to jam. We love challenges, they make…
And this pretty impressive article that lets me rediscover PHP in an other way
Cooperative multitasking using coroutines (in PHP!)
One of the large new features in PHP 5.5 will be support for generators and coroutines. Generators are already…
Great presentation slides to understand asynchronous vs concurrent php code https://b-viguier.github.io/downloads/talks/ForumPhp2019-AsynchronousPhpInProduction.pdf