Poll Everywhere is a bunch of single-page applications that talk to a back-end Rails API server. In an ideal world, we’d be serving most of our assets from S3 buckets on AWS with a cluster of servers that handle back end functionality.
Brad gave a talk at RailsConf that is a good overview of Poll Everywhere’s current architecture and it’s evolution over the past 7 years. Are videos not your jam? Read on.
Why did Poll Everywhere choose Rails as an application server? Because back in 2007 Brad made this commit:
commit 8792daca53ba186110638d3ad130f1c10ad0c43b Author: bgessler <bgessler@e22565e0-692d-0410-a74b-dd4a38dae0e6> Date: Thu Apr 12 00:04:27 2007 +0000 Added the rails project to the SVN repository. git-svn-id: http://svn.patrickandallenonline.com/tallyr/trunk@2 e22565e0-692d-0410-a74b-dd4a38dae0e6
We’re still running this Rails application in production today. Don’t worry, we’ve upgraded it all the way from 1.2.3 to the latest version of Rails and we use git.
Lately we’ve been breaking apart our server-side application into several smaller Sinatra and NodeJS applications to make it easier for our larger engineering team to make changes more quickly. We’re pragmatic about deploying microservices; it’s not a dogma or top priority to take everything and break it into little pieces.
We run our application under pretty harsh conditions.
First, have you ever been to a conference? Remember how crappy the WiFi is there? We have to make sure our applications can deal with flakey internet connections. The best way we’ve found to do that is to push a big JS, CSS, and HTML payload down to the client device once, then have it connect to our servers so that we can handle the connection handling (and attempt to reconnect if the connection drops). We developed our own real-time web server, Firehose, to deal specifically with streaming data over crappy internet connections.
Second, our app does a bunch of stuff in realtime. It needs to be really fast and responsive.
Third, we have some pretty cool application frameworks built by our app team. These frameworks expose JS APIs to our front end code that allow us to do cool things like remotely control a PowerPoint presentation from Poll Everywhere in any web browser.
Finally, it allows us to scale more easily. If we have 100,000 people hit one of our voting pages, all we have to do is serve up static JS, HTML, and CSS assets. When a bunch of people submit their votes, our response processor can focus on that piece of heavy lifting.
The major downside is the error reporting can be lacking. We use source maps to capture production exception telemetry, but it’s not perfect.
We invest a lot of energy into deep integrations with operating systems like iOS & Android and applications like PowerPoint and Keynote.
Our approach is to keep these applications as thin and consistent as possible by reusing our HTML, JS, & CSS user interfaces. Using our app team’s cross-platform hybrid application framework, we gain all the benefits of web development with the speed and reliability of a compiled application.
We think of architecture as the state of things now. We might discover that single-page JS applications are not the way to go for a particular application or problem. If that’s the case we’ll go with what best solves that problem (server-side rendering?).