Going Async in Symfony Controllers
Within the browser environment, individual events like clicking and are entered in an event loop (see Philip Roberts: What the heck is the event loop anyway?) which are then processed asynchronously: There is no guarantee on the order of when the click events will end execution.
The beef of going async is I/O. In the browser the concept was enabled in Internet Explorer 5.0 and popularised by Gmail in 2004. The method, coined as AJAX allowed the browser to make requests to the server after the initial page load.
Non-blocking asynchronous I/O on the server enables the server to continue performing other tasks instead of waiting for a long running database call, for example. There are a number of mechanisms for handing the flow of asynchronous code, such as futures/promises, generators and observables.
So asynchronous programming does not push your computer into overdrive to enable higher performance. What it can do is help the computer to use it's resources more efficiently, by removing time spent waiting.
By tradition PHP folllows the synchronous programming model. The computer performs the operations in the order they are given. This makes it straightforward and predictable to read code and anticipate the outcome.
The downside is that PHP can potentially spend a large portion of the execution time doing nothing, waiting for a remote server to respond with results or something else. This time could be spent better by proceeding with other tasks and returning to processing the DB results once they're done.
In the recent years there has been increased activity in the realm of Async PHP with projects such as React, Amphp, Icicle and RxPHP. There is also a book on Asynchronous PHP in the works. In addition the alternative PHP runtime HHVM and the PHP derivative Hack language has adopted async techniques.
During 2015 and early 2016 there has been positive advancements in this space for PHP. A number of the abovementioned efforts have joined the PHP-FIG (PHP Framework Interoperatibility Group) to work together to create conforming implementations and a PHP Async Interop Group has been formed:
As you can see PHP is capable of working within the async paradigm with a number of event loop implementations, starting from native PHP implementation.
Asynchronous controllers in Symfony
The Symfony Framework itself is synchronous as the code flow is static, starting and ending to the front controller in a logical way. You can do asynchronous programming by deferring tasks to message queues to be handled by another process.
Sending emails or doing database maintenance tasks are great candidates for deferring to another process. But for tasks that you need to do within a scope of a single request, the asynchronous methods above can yield (pun intended) great results.
A typical example would be a request sent to a Content Management System that needs to generate a number of elements from a database to form a page for display. With Symfony you can use the fragment sub-framework and run tasks in parallel using ESI or Hinclude.
The controller simply returns a number of messages to the template. In this case, however it is done with a delay of one to five seconds. If done synchronously all the delays would add up to a maximum of 25 seconds. With coroutines the maximum runtime will be around fine seconds.
To gain asynchronous I/O your source needs to be non-blocking. Many common utils such as the MySQL library remain blocking, rendering async techniques useless. There are workarounds like Amphp MySQL, but it will take some time before the ecosystem is mature enough for async support to be default.
Mixing synchronous and asynchronous flows within a Symfony application seems like a valid use case. Explicitly entering an asynchronous loop when needed also keeps the code quite readable for developers used to the synchronous programming model.
Learn more about Async PHP:
- The promise of asynchronous PHP
- Build a Superfast PHP Server in Minutes with Icicle
- Getting Started with Icicle
- Asynchronous PHP - Christopher Pitt
- Async PHP with React