To achieve this we needed to understand how other applications are doing it, decide on an approach that would work with the clients requirements and our skill set and build something measurable which would prove that we could deliver a solution that would be capable of meeting the clients’ needs within their budget.
And the challenge? We had to do all of this within a single proof of concept sprint (2 developers and 1 week).
Before we began building the proof of concept, we needed to gain a greater understanding of the technologies that were available to us. We embarked on a mission to research how other applications are dealing with real-time data and discussed as a team once each of us had a reasonable understanding.
Our research pointed towards WebSockets as the best way to deal with real-time data. WebSockets is web protocol which establishes a persistent connection between the client and the server, allowing both parties to send messages at any time. WebSockets is used by many large applications to provide a real-time solution. One notable case study of an implementation is by Trello, which is definitely worth a read if you’re interested in real-time applications. Incidentally, Trello is a web application we rely on for our day-to-day workflow.
In the course of our research we evaluated a number of “out of the box” solutions such as SocketStream, Derby, Meteor, and a fully hosted service called firebase. Whilst all of these solutions might do part of what we wanted and were very easy to set up, none were quoted as “production ready”. The upshot is they might have been useful for us in our proof of concept as they would allow us to get something up and running very quickly but when it came to building the actual application these solutions would not put us on a good footing, so we ended up discounting them. The real decision was based on what would work for us not only for the proof of concept but for the more challenging software itself.
Real-time for UVD
Building the proof of concept
Initially we wanted to have the data stored in a MongoDB database because MongoDB is often seen as the natural partner for NodeJS and for real-time applications the schemaless data structure and speed of data insertion appealed to us. After digging a bit deeper though, it became evident that it might not satisfy all of our requirements for data storage because whilst it has transactional support at a document level, it is not ACID compliant. Our application would require us to insert multiple documents into the database in one transaction and we needed to be confident that in the event of an error during insertion or updates to the database, there would be a consistent result. You can see this problem occur on Trello when you use a feature like ‘Archive all Cards in This List’ and it fails half way through – the result can be that some cards are archived and some remain on the board. This is acceptable for Trello but definitely not for our application.
Since MongoDB does not have transactional support we needed to look into some alternatives and after some further research of different NOSQL and SQL databases, we decided to see how well MySQL would fare. We know MySQL very well, it has transactional support and can perform well for smaller data sets.
There were several aspects of the implementation that we wanted to isolate and test. These were network latency, database speed, and browser speed. To test all of these aspects we configured the proof of concept to run on our local machines and inserted code to spit out a timestamp at a few key points in the application. This allowed us to track where time was being spent.
To test network latency, we set up 2 servers in different locations. We already make extensive use of Amazon Web Services (AWS), so we were able to quickly set up one server in EU-West-1, which is based in Ireland, and another server in Sydney, Australia. We chose Sydney as it’s the furthest data centre away from us here in London.
The different database types were tested by switching out the persistence of data in the backend from MongoDB to mySQL. Once this was working satisfactorily on our local machines, we put these applications on our 2 servers, and re-ran the test.
Cross browser support is important, so we compiled a list of browsers we wanted to test based on the way they dealt with WebSockets. Chrome was an obvious choice, has full WebSocket support, and is used by most (if not all) of us here. Firefox 21 is another good browser and has full WebSocket support, so we wanted to see how it compared to Chrome. Delving into IE is always a bit of a minefield and the one we were slightly apprehensive about. IE provided a good opportunity to test how much of an effect SocketIO’s fallback systems would have on performance. IE 10 is the first IE browser to have WebSocket support, so we added it to the list in case Microsoft had added any ‘eccentricities’ to it’s implementation but the lowest version of IE we were required to support was IE8 and as it doesn’t have WebSocket support, this was where SocketIO’s built in fallbacks came into play. The first relies on Flash and if Flash is not installed, it downgrades to long polling. We therefore needed to test with and without Flash.
All of these different variations were tested and averaged over 10 and 60 iterations to give us our results.
We knew that we had to be able to provide near real-time data (end-to-end in under 1 second) but as our proof of concept wasn’t a full implementation we assumed that there would be some factors in the finished product which would slow the application down so we decided to err on the side of caution when analysing our results. Any completed event in less than ½ second would be good (marked green above), anything between ½ a second and a second would be satisfactory (marked amber), but more attention would be required and anything over a second is a failure (marked red).
As you can see in the table above, we were mostly green, with all red and amber times being on the servers with the greatest distance to travel. Another interesting point to note is that the difference in times between MySQL and MongoDB were generally insignificant. We were expecting MongoDB times to be hugely different, but these variances were not significant enough for us to rule out MySQL as a possibility.
Our first foray into real-time applications was an interesting learning experience for us and after a lot of research, some well thought out planning and a quick, iterative approach to implementation, not only were we able to get the proof of concept complete and tested within 70 hours but the results proved that given our technology choices, we had utmost confidence in our ability to build an application that satisfied the client’s requirements without an unsatisfactory level of investment or risk.