A synchronized rolling release

Learn how to implement update notifications

Portraitbild der/des Autor/in Thomas Kirchner
None

What's bothering?

Today we're getting down to the nitty gritty! In this blog post, you'll get exciting tech insights on our current development of Mataono, a web-based consulting software for the banking and insurance sector that works with emotion analysis and speech recognition, among other things. We are developing Mataono in an agile rolling release process to continuously test individual components, incorporate feedback and add more features. Within our workflow, the following problem manifested itself: The latest version of the software is not visible to all team members in their browser. The reason for this is persistent cache data. So how do we ensure that the latest version of Mataono is visible at all times, regardless of the browser?

That's how it turns out...

We work with the Vue.js framework because, among other things, it works with many small request-response cycles. Requests are sent to the server in short intervals. The server's responses in turn only lead to changes in the DOM where they are needed. Thus, the complete reloading of a page by the browser is avoided and leads to a noticeably better performance. Vue.js manipulates not only data, but also its presentation in the interfaces of an application. To ensure that the current version is always displayed in the user's browser despite all the above-mentioned small details, there are two basic problem-solving steps: informing the Vue app that a new version is available and then processing and visualizing this information in the browser.

...and that's how it turns into code!

Step 1 - Inform the Vue app

The Vue app itself has stored its current version. To tell the app that there is a new version, the server has to answer each request with information about the current version. The backend is programmed using Django, allowing data to be delivered using the Django REST framework. Help is provided at this point by middlewares that hook into the request-response cycles. Using an onion with its individual layers (= middlewares), through which a needle is pushed, the process can be clarified: If it arrives at the center of the onion, the request is processed there and the corresponding information for the response is added. In our example, a middleware ensures that a header with the current version number is inserted. With this solution, each response of the server does not have to be adapted separately, but the adaptation only takes place at one point.

class FrontEndVersionMiddleWare(object):
    """
        Middleware which adds a header to determine the currently most recent vue-js-mataono version
    """
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request: HttpRequest):
        response = self.get_response(request)
        if settings.FRONTEND_VERSION:
            response['FRONTEND-SERVER-VERSION'] = settings.FRONTEND_VERSION
        return response

Step 2 - Inform the users

The next step is to inform users that a new version is ready. To do this, we need a central point of contact in our software.

In the Vue app we use axios, which takes care of handling the requests sent. Basically, this library adds the web address of Mataono to the beginning of each request we send. In addition, axios can also be used to implement so-called interceptors. For example, we use one of these interceptors to add the current language of the user to the headers of every request we send to the server. This ensures a consistent translation.

axiosInstance.interceptors.request.use(function (config) { 
  const token = localStorage.getItem('authToken')
  const language = localStorage.getItem('currentSelectedLanguage')
  if (token !== null) {
    config.headers.Authorization = 'Token ' + token
  }
  if (language !== null) {
    config.headers.common['Accept-Language'] = language
  }
  return config
})

Since we now know from each response of the server about the current version, we have implemented an interceptor for the responses, which compares the version sent by the server with the version known to itself. If they do not match, the interceptor sends an internal message, which is processed by the Mataono app, displaying a message to the users.

axiosInstance.interceptors.response.use(function checkResponse (successResponse) { 
  if (successResponse.headers['frontend-server-version'] !== version) {
    window.dispatchEvent(
      new CustomEvent('vueVersionUpdated')
    )
  }
  return successResponse
}, undefined)

export default axiosInstance

Why this makes us happy

The solution with update notifications offers two major advantages for the further development of Mataono and can be transferred to other applications: On the one hand, our developer team does not have to adapt each response individually, but can do this in a single place. Second, users receive a notification as soon as a new software component is added. A popup informs about the current version and it is no longer necessary to take care about deleting old cache data. In our daily work process, this simplifies test phases, avoids misdiagnoses and saves an incredible amount of time.

Special thanks to Sami and Steffen, two of our backend developers, who supported me in realizing this blog post!

Written by
Portraitbild der/des Autor/in Thomas Kirchner Thomas Kirchner
Tom ist Kreativkopf bei descript. Durch seine Ideen und Visualisierungen werden unsere Software-Anwendungen nutzer:innenfreundlich und barrierearm. Er ist außerdem unser TÜV-zertifizierter Experte für Datenschutz.
Lass uns im Gespräch bleiben Du findest den Beitrag spannend?

Das Thema des Beitrages interessiert dich? Du möchtest dich darüber austauschen, deine Meinung kundtun oder zukünftig mehr von uns lesen? Dann folge uns auf unseren Kanälen bei Instagram und LinkedIn.