Customization within Multi-Tenant Platforms
Using a cloud-based multi-tenant architecture for your software product works great. Every one of your customers is served from a single installation. Upgrades are simpler to perform compared to an on-premise operation model. It might even be the case that only a single version of your software is installed in your entire environment.
It all looks great. Then one day the whole team meets to plan the next iteration of the product. The conversation could start like this: “Good job guys pushing out the new release yesterday! It’s fantastic to use our new search functionality. Let’s release it to beta users next week. And to paying customers at the end of the month.”
As outlined in the beginning of this article using a multi-tenant platform is beneficial from an operators point of view. However, the price one has to pay lies in the increased complexity. The same installation will need to be customized in terms of branding, work flow, or even access control. At Squirro we are building exactly such a multi-tenant platform to serve all of our customers. In order to e.g. customize a certain work flow there is a central service which allows configuration values to be stored in an efficient and hierarchical manner.
What works great is to exploit the fact that configuration values can be the same for a set of users. You can for example define which logo to show in your front end web application for all users of a single customer. For storage and maintenance reasons you are better off to not store this information for every user individually. However, the hierarchical nature of the system still accounts for the fact that a single user might have a different need. In the picture below you can see how configuration values are organized. At the very top there is always a default entry for any configuration value that is stored within the system. Below that users can be grouped into tenants and groups. At the bottom level a value can be present for a single user.
As our architecture is based on independent HTTP services the configuration values stored on persistent storage are exposed via a RESTful interface. Any module that needs to fetch values from the configuration service uses our Python client library. It abstracts away all the boiler plate HTTP calls and the corresponding error handling routines. Moreover, the library contains a time-based cache which expires cached entries after a given time period. Such a design makes sure that on one hand the service is not contacted on every request to get the same configuration value. On the other hand a time based cache makes sure that updated values on stable storage get propagated eventually.
So let us walk through an example and see how things look in actual Python code. The goal is to query the configuration service to check whether the improved search functionality is enabled for a particular user. First we import our client library and create a new client. Then we can query the service and make sure that configuration values are stored within an in-memory cache of the current process.
The code example above shows how to get the default value which is used as a feature switch. But now the hierarchy of the system allows us to store values for all users of an tenant. Or we can fine tune the setting for an individual user. In the code example below it is shown that the new search functionality has been enabled for a particular software engineer who is currently testing the new feature. All the other members of the team get the value which is defined for the tenant.
There are many use cases for the usage of a configuration service within a multi-tenant environment. The scenario of work flow customization has been highlighted above. Taking advantage of the hierarchical nature of configuration values is crucial to make such a service scale and be used throughout a multi-tenant platform.
Open position: Senior Python Developer @ Squirro
We are looking for an experienced Python developer for full-time employment.
You will be part of the core platform team building Squirro, the personal digital research assistant. Within days you will be taking over the responsibility for sizable portions of this new platform. You’ll be part of a small developer team building a scalable real-time application. And that 100% in Python.
Together we’ll build an open platform based on REST web services.
- Extensive experience with Python
- Familiar with HTTP / REST, especially aspects such as performance and caching
- Familiar with asynchronous processing and queuing, for example using RabbitMQ
- Experience with testing and test-driven development
- Work permit in Switzerland, which is given for citizens of EU and EFTA member states
Existing knowledge in any of the following is not required but helpful:
- Experience with search technologies such as Lucene, Solr, ElasticSearch
- Cloud deployments, especially with Amazon Web Services
- Configuration mangement with Puppet
Squirro is a Swiss startup. We are a team of passionate Internet geeks and entrepreneurs. We love Python and are very open about how we develop. We mainly use Flask and our own WsgiService at the moment. We work with Git, believe in testing, continuous integration and continuous deployment. Our work is structured with Scrum.
We are located in Zurich, Switzerland. The city has repeatedly been rated as one of the very best cities to live in.
In the first phase we built the online note-taking tool Memonic.com available on the web as well as mobile and desktop devices. Now we are expanding the Memonic platform to become a real-time knowledge gathering tool. Call it the next level of note-taking.
- Patrice Neff
- Email: firstname.lastname@example.org
- Skype: patriceneff
- Phone: +41 44 586 98 98