Parallel CMS
The most common pattern for web applications is that the web server waits for requests, and when it receives a request it executes the application which handles the request and returns data to the web browser. When the web server is waiting, the web application is not running. It’s not even in a waiting state, it’s simply not executed. When the web server receives a request, it fires up the application, which performs routing, handling of data, lots of other stuff, and eventually returns data to the web browser.
Maybe the web server does some caching to speed up the load of the code, but the pattern is that when there are no requests, no web application is running — except the web server and database, but that’s a different story. Only when there is a request, the server application is executed.
It can take quite some time to perform this bootstrapping of the server application, especially if it’s an advanced application with a lot of custom code, e.g. a CMS (Content Management System) with lots of modules/extensions. On top of that, the code is normally run sequentially, so the more code to run and the more data to return to the web client, the longer it takes for the server to execute the code.
Why not choose another path?
Instead of the described pattern, the web application could be executed and running — ready to serve — before receiving requests from clients. And if the web application also performs as much as possible in parallel, it will both be quickly serving clients and perform quickly — whatever it performs — before it returns data to the client.
This article describes this loose concept of a parallel CMS.
Disclaimer
These are just my ramblings. If you think I’m saying something rubbish, my assumptions are wrong, or that what I’m writing is off in some way, then please tell me.
If what I write is lame or trivial, then please also tell me that.
If you have any other reason to comment, then please do.
Always running — ready to serve
There are more aspects in this article, not just parallelism. It’s perfectly possible to build a web app that exploits multiple cores efficiently, but not performing any bootstrapping before the web request.
I’m suggesting a CMS that does both. It’s executing and ready to serve at any point, so that any response to a request will not have any bootstrapping overhead. It (almost) doesn’t matter if it takes long to boot up the application, as long as it responds quickly to requests.
The reason that web applications normally aren’t running before the web server receives a request is because it’s easier. If you want the application to be resident in memory, you need some sort of concurrency handling between different processes in the operating system. It’s easy for the web server to execute the application with some input, wait for the application to finish, and return the output.
Concurrency handling requires communication between running processes, and depending on the method of interprocess communication it can require locks and semaphores (if the chosen method is shared data between processes).
There are some advantages when choosing message passing, for instance race conditions don’t exist as no two processes shares data and will therefore not try to access the same data at the same time. Deadlocks can occur, though.
Run everything in parallel
One obvious advantage to splitting work to multiple cores is speed. It’s faster to perform the same workload when it can be split up and run in parallel on different processes/cores. That’s the main reason for parallelizing software.
Often the total workload is bigger when run in parallel because of overhead in splitting the task. Some tasks can be easily parallelized without this penalty — these types of problems are called embarrassingly parallel problems. In general that’s not the case, though, so the total workload will be bigger. But the advantage of using a parallel architecture is that it finishes faster, even if there is some overhead. We want this, because we want to finish the handling of data and return the result as quickly as possible to the end user.
Return quickly
Another thing to consider when building a parallel CMS is that even though everything is run in parallel, some processes might not finish quickly. We don’t want to ruin the advantages of running in parallel, if we still have to wait for a single slow process. So why not just return when enough processes (or just the main process) have finished? If we make sure, that the most important parts of the web page are returned when they are ready, the rest of the web page can be fetched after the initial load in the order it finishes. This ensures that the user receives part of the result as quickly as possible, which makes the perceived performance better, and the user will receive the rest of the data soon enough. It’s common to use this “trick” in different ways — some loads the rest of the data asynchronously.
This approach also has the advantage that you don’t need to consider, exactly which parts of the web page that can be deferred until later — you just receive it when it’s done. If one process for some reason takes abnormally long time and would normally finish very quickly, it doesn’t ruin the performance of the other processes’ work. The web page is still served to the user quickly, even though some parts take longer. So if implemented properly, this method will work in the general case.
If instead you had to analyze your application to find the exact parts that should be loaded asynchronously, you might not catch all of them, and it could be quite time consuming.
Piped handling of input and output data
See my thoughts on a topic related to message passing: https://medium.com/@mortenbartvig/generic-handling-of-input-output-data-a38a1de1b6f4
If this concept is implemented in the CMS and the parallel architecture is sufficiently sane, it would be easy to make extensions/plugins/modules in different programming languages, as long as they follow the same protocol and standard. You just have to make sure to plug in to the right input/output stream, change the data from the source, and send it to the destination (the destination can even be a different destination than the original data stream, or it could be both). This way you don’t need to learn a specific programming language to be able to extend the CMS. You would need to know where to hook in to the data streams, though, but nothing is a silver bullet.
If your plugin doesn’t need to interfere sequentially with other parts of the system, e.g. if you need the output of a part of the application without changing it, the plugin could run parallel to the rest of the CMS and plugins and wouldn’t even affect the overall speed of the CMS. Of course, in a real world scenario some plugins will affect the speed, but it will not affect it in the same way as a normal, sequential application. In a normal, sequential application, every plugin or extension that needs to do some kind of work for the current request will affect the speed of the application.
Conclusion?
I haven’t described a full content management system, but only suggested a loose concept of a parallel architecture that I think would be interesting to build. Maybe something of this sorts already exists, but I haven’t seen it and it’s definitely not common practice yet.
What are your thoughts?
This has also been published on LinkedIn: https://www.linkedin.com/pulse/parallel-cms-morten-bartvig