Synchronisation im Rolling Release

Hier erfährst du, wie du Update-Benachrichtigungen implementierst

Portraitbild des Autors Thomas Kirchner
1. September 2021
None

Wo drückt der Schuh?

Heute geht’s ans Eingemachte! In diesem Blogbeitrag bekommst du spannende Tech-Einblicke in unsere aktuelle Entwicklung von Mataono, einer webbasierten Beratungssoftware für den Banken- und Versicherungsbereich, die unter anderem mit Emotionsanalyse und Spracherkennung arbeitet. Wir entwickeln Mataono in einem agilen Rolling-Release-Prozess, um kontinuierlich einzelne Komponenten zu testen, Feedback einzuarbeiten und weitere Features hinzuzufügen. Innerhalb unseres Workflows äußerte sich folgendes Problem: Nicht alle Teammitglieder sehen die neuste Version der Software in ihrem Browser. Grund dafür sind hartnäckige Cachedaten. Wie gewährleisten wir also, dass zu jedem Zeitpunkt, browserunabhängig, die aktuelle Version von Mataono sichtbar ist?

So wird ein Schuh draus...

Wir arbeiten mit dem Framework Vue.js, weil es unter anderem mit vielen kleinen Request-Response-Zyklen arbeitet. In kurzen Intervallen werden Anfragen an den Server gesendet. Dessen Antworten wiederum führen nur zu Änderungen an den Stellen im DOM, an denen es benötigt wird. Das vollständige Neuladen einer Seite durch den Browser wird somit vermieden und führt zu einer spürbar besseren Performance. Vue.js manipuliert nicht nur Daten, sondern auch deren Darstellung in den Oberflächen einer Anwendung. Um sicherzustellen, dass bei all der genannten Kleinteiligkeit stets die aktuelle Version im Browser der Nutzer:innen dargestellt wird, ergeben sich zwei grundlegende Schrittfolgen der Problemlösung: Die Vue-App darüber zu informieren, dass eine neue Version vorliegt, sowie die anschließende Verarbeitung und Darstellung dieser Information im Browser.

...und so ein Code!

Step 1 – Die Vue-App informieren

Die Vue-App selbst hat gespeichert, in welcher Version sie vorliegt. Um ihr mitzuteilen, dass sich die Versionen unterscheiden, muss bei jeder Serveranfrage mit einer Information über die aktuelle Version geantwortet werden. Das Backend ist mittels Django programmiert, sodass die Daten mittels Django-REST-Framework ausgeliefert werden. Hilfe bieten an dieser Stelle Middlewares, die sich in die Request-Response-Zyklen hängen. Anhand einer Zwiebel mit ihren einzelnen Schichten (=Middlewares), durch die eine Nadel geschoben wird, lässt sich der Ablauf verdeutlichen: Kommt sie im Zentrum der Zwiebel an, erfolgt dort die Verarbeitung der Anfrage (=Request) und die entsprechenden Informationen für die Antwort (=Response) werden hinzugefügt. In unserem Beispiel sorgt eine Middleware dafür, dass ein Header mit der aktuellen Versionsnummer eingefügt wird. Mit dieser Lösung muss nicht jede Response des Servers separat angepasst werden, sondern die Anpassung erfolgt nur an einer Stelle.

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 – Die Nutzer:innen informieren

Im nächsten Schritt müssen die Nutzer:innen darüber informiert werden, dass eine neue Version bereit ist. Dafür benötigen wir einen zentralen Anlaufpunkt in unserer Software.

In der Vue-App benutzen wir axios, welches für das Handling der gesendeten Requests sorgt. Grundsätzlich ergänzt diese Bibliothek die Webadresse von Mataono an den Anfang eines jeden von uns gesendeten Requests. Außerdem können mit mit axios auch sogenannte Interceptoren implementiert werden. Einen dieser Interceptoren verwenden wir beispielsweise, um an jeden Request, den wir zum Server senden auch die aktuelle Sprache des Nutzers in die Header zu schreiben. Somit sorgen wir für eine konsistente Übersetzung.

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
})

Da wir jetzt von jeder Antwort des Servers wissen, welche Version die aktuelle ist, haben wir auch einen Interceptor für die Responses implementiert, welcher die vom Server gesendete Version, mit der selbst bekannten Version vergleicht. Falls diese nicht übereinstimmen, sendet der Interceptor eine interne Nachricht, welche von der Mataono-App verarbeitet wird, sodass den Nutzenden eine Meldung angezeigt wird.

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

Warum uns das glücklich macht?

Die Lösung mit Update-Notifications bietet zwei wesentliche Vorteile für die weitere Entwicklung von Mataono und lässt sich auch auf andere Anwendungen übertragen: Zum einen muss unser Entwickler:innenteam nicht jede Response einzeln anpassen, sondern kann dies an einer einzigen Stelle tun. Zum anderen erhalten die Nutzenden eine Benachrichtigung, sobald eine neue Softwarekomponente hinzukommt. Ein Popup informiert über die aktuelle Version und es ist nicht mehr notwendig darauf zu achten, alte Cachedaten zu löschen. In unserem täglichen Arbeitsprozess vereinfacht das Testphasen, vermeidet Fehldiagnosen und spart unglaublich viel Zeit.

Ein großes Dankeschön geht an dieser Stelle an Sami und Steffen, die als zwei unserer Backend-Entwickler erheblichen Beitrag zur Umsetzung des Blogbeitrages geleistet haben!


Teile diesen Beitrag, wenn er dir gefallen hat: Teilen:

Wer hat's geschrieben?

Thomas Kirchner

Portraitbild des Autors Thomas Kirchner
Tom ist Geschäftsführer und Kreativkopf bei descript. Durch seine Ideen und Visualisierungen im Frontend werden unsere Entwicklungen zu nutzer:innenfreundlichen, barrierearmen und harmonisch gestalteten Anwendungen.
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.