We have a killer app program. For each vertical we offer an advanced, customer-proven pre-packaged solution that brings you best practices on the methodologies and KPIs in the given business. We wanted to bring the benefits of our apps to as many people as possible and give you a try-before-you buy experience of the GoodData apps. That’s why we built web-based trial wizards for our most popular apps:
These self-service tools guide you through a few simple steps:
- You give us contact information, so that we can help you evaluate the app.
- You grant us access to your data residing in the cloud (Salesforce or Yammer). Granting access is done in a secure way using OAuth - you don’t have to give us any passwords, you just give access to our app in the cloud. Permission can be revoked at any time.
- For the sales app you also need to provide some basic information about your Salesforce implementation so that the wizard knows where to take the data from.
- A background process downloads your data and loads it to the GoodData platform.
- When everything is ready, we invite you to the GoodData project where you can get unprecedented insights to your data, analyze trends in ad-hoc reports and evaluate the app before you buy.
How we built it and why
The goal was to build it fast and agile so that we can iterate and incorporate feedback of different users as fast as possible. Even though the GoodData platform is very agile, we release major versions every month and new minor versions every other day, we decided to build the trial tools outside of the GoodData platform so that we could iterate even faster. When designing the trial framework, we had to make a few decisions that we’d like to share. We’d be thrilled if our process could motivate others to build something similar!
Nowadays building agile apps means using a dynamic typed scripting language. You can express more with less code. You don’t have to care about compiling your code and changing the code is generally easier. When building our trials we wanted to leverage the tools we already have: GoodData Ruby. That’s why we chose Ruby.
Deployment: Internal Infrastructure vs. Heroku Application Platform
Another advantage is scaling - by adding a few web or worker nodes, we can accommodate as many users as we want.
As we share some API resources for all the trials, we use a single git repository for all trial wizards. Only the environment variables indicate which app is currently running. That way we can set up or tear down development environments in just a few minutes, using separate Heroku apps. Code sharing and agile deployment enabled us to come up with new app wizards quickly. For example, we prepared the wizard that builds Yammer Analytics within a week.
Background jobs: Resque
Sooner or later, every web app developer comes to a point where synchronous request processing by a web server is not enough. Some actions, as downloading data from external systems usually take a long time and the web server can’t wait with the response until they finish. At that point it’s necessary to employ another node (Heroku “dyno”) that performs the long actions and stores the results when ready. For background job processing, we used a ruby library called Resque. On top of that we built a REST API resource for starting an action and another one for getting the result of the action (or a response that the action hasn’t finished yet).
We had to do a few tweaks to make Resque work for us seamlessly. Some actions (e.g. data downloads) don’t have to fully employ the node, as they’re only waiting for another server to finish. For these type of tasks we introduced a special type of job that periodically checks status on the remote server without fully employing the node.
Another tweak we had to do is related to the way how Heroku handles job termination. For each job we had to implement a strategy how it should react when Heroku sends it a TERM signal. Most jobs are just enqueued again and the action is repeated. For the same reason we couldn’t expose the job identifiers from Resque on our REST API: when a job is re-enqueued it gets a new identifier and the old one isn’t valid anymore. To solve that issue we introduced a mapping layer between the Resque identifiers and identifiers exposed by the REST API. Before a job is terminated, it updates its Resque identifier in the mapping.
The way we built the trial wizard shows that powerful apps can quickly be built outside of the GoodData production environment on top of the platform API. Using different frameworks and services we were able to come up with an app that was developed rapidly, uses up-to-date technologies, and scales as needed. Special thanks to all teams and individuals that helped us along the way!