Asynchronous Programming : Site Speedup Techniques
Many of the lengthy tasks that server side scripts execute are tasks on which the scripts are waiting for some other program, hardware or remote computer to respond.
For instance, when your scripts accesses a database, it has to establish a connection and then it executes database queries. During most of the time that your script is establishing connections and executing queries, the script itself is doing nothing else, just waiting for the request data to be sent to the database server and then waiting for the database server to respond.
What if instead of just waiting for the database server to receive or respond to requests, your script could actually do something else in parallel? That is the premise of asynchronous programming.
What is asynchronous programming?
Imagine that you have a Web site page that is made of content of retrieved from a database running several queries. Usually you run one query, wait for the response, retrieve the results into some variables, run another query, wait for the response, retrieve the results into some variables, and so one. Only at the end you assemble all the data to generate the resulting HTML page.
Now, imagine if instead of waiting for the results you could immediately start the next query while the database does not return the response for the first query? You could eventually gain a lot of time.
Asynchronous programming in JavaScript
One example of client side programming language that provides built-in support for asynchronous programming is JavaScript. On the browser side you often define what code is called when different types of events happen.
You can do that for instance assigning the ON attributes of page tags (ONCLICK, ONMOUSEOVER, ONCHANGE, etc..).
<div id="mydiv" onclick="alert('Click!');">Click me!</div>
Alternatively you can call functions of certain page element objects to register event callback functions, like addEventListener.
<div id="mydiv">Click me!</div> <script type="text/javascript"><!-- document.getElementById('mydiv').addEventListener( 'click', function() { alert('Click!'); }, false); // --></script>
Asynchronous programming in PHP
In PHP everything is synchronous by default. This means that when you call any function, PHP always waits for the function to finish the job and returns the result at the end.
Currently PHP does not provide any built-in form of support of doing asynchronous programming using callbacks. There is some support to implement asynchronous programming in PHP using the function stream_select. This function lets PHP scripts poll opened files or network connection sockets to see if reading or writing data to files or the network would block. PHP can tell the function to wait for a given period until any data is received or has finished to be sent.
This is clearly insufficient to do full blown asynchronous programming in PHP. The limitation is not in the PHP language itself. It is rather the PHP extensions that could provide built-in asynchronous support but currently they don’t.
An alternative solution to implement asynchronous programming in PHP is to use Gearman. For those not familiar with Gearman, it is a middle-ware program that acts as a server that can take calls to functions implemented by worker programs that run on the background.
The worker programs themselves can be written in PHP and so they can implement any functionality you need. Worker programs can be running on the same machine or even in remote machines. One useful feature of Gearman that can enable asynchronous programming in PHP is the support to call jobs asynchronously. This means that when job is called, the calling script does not have to wait for the job to finish. Collecting the results of asynchronous jobs can be done but it is tricky, so this solution is not ideal.
Another solution is to use the PHP pcntl extension to fork new processes and run PHP scripts in parallel. While this solution may work to some extent, it is expensive in terms of CPU and memory that are necessary to fork new processes.
PHP got closure support in version 5.3. Closures are basically anonymous functions that may be used directly to define a callback function right in the function call that takes a callback handler. It was a good PHP evolution step as it makes callback based asynchronous programming a more developer friendly in PHP
In sum, I would say it will take some time until asynchronous program becomes a more natural thing in PHP. Still there are a few use cases on which it would be worth doing it, even with current PHP’s limited support.
- Asynchronous Programming : Site Speedup Techniques - March 25, 2014
- Why All PHP Frameworks Suck? - February 19, 2014