Artikelformat

Asynchrones Dilemma

Asynchrone Requests machen das A in AJAX aus und bieten viel Raum für interessante Betrachtungen. Hier geht es heute um das Problem, das veraltete Anfragen sauber erkannt oder alternativ ein hohe Anzahl von Antworten schnell verteilt werden sollen. Anhand einer Abstraktion werde ich den ersten Punkt beispielhaft beschreiben.

Aktuell bin ich in einem Projekt eingebunden, das sehr viel mit asynchronen Aufrufen arbeitet. Da es sich um eine Webapplikation handelt, ist dies nicht ganz so verwunderlich. Aber zuerst eine kurze Beschreibung des Problems.

Der Anwender kann durch eine Aktion einen Request (A1) auslösen, der – sobald die Antwort vom Server verarbeitet wurde – einen zweiten Request (A2) auslöst. Dessen Antwort kann unter Umständen beliebig viele weitere Requests (A1′) starten, die dem ersten ähneln. Wobei „beliebig“ berechnet werden kann und einen maximal Wert hat.
Währen der Verarbeitung der A-Requests- und Response-Daten kann der Benutzer weitere Requests auslösen. Bspw. B1, C1 und D1. Das System verarbeitet diese neuen Requests wie den ersten und wir haben eine wahre Flut von Requests.

Das beim Auslösen von Request B1 die Komponente, die alles verwaltet partiell zurückgesetzt wird, hat man das Problem, das die Antwort von A2 nach dem zurücksetzen eingehen kann und damit zu einem inkonsistenten Zustand führen kann.

Der anfänglich theoretische Zustände konnte bei entsprechenden Benutzung erreicht werden. Somit war die Anwendung an dieser Stelle nicht robust und musste angepasst werden.

Wir haben uns für das ACT-Pattern entschieden. Also einen Asynchronous Completion Token eingeführt. Das heißt, sobald der Request A1 gefeuert wird, setzen wir einen Token in der Komponente und geben diesen dem Request mit. Alle Antworten und Requests, die aus A1 resultieren, müssen diesen Token mitführen, sonst werden sie verworfen und somit die Verarbeitung abgebrochen.

Löst der Benutzer B1, C1 und/oder D1 aus, wird der Token der Komponente neu gesetzt und somit können veraltete Antworten identifiziert werden. Dadurch haben wir die Komponente immer in einem gültigen Zustand.

Als Token nutzen wir aktuell einen Zeichenkette mit 10 Zeichen, die zufällig aus dem Alphabet (inkl. Groß- und Kleinschreibung) und den Zahlen von 0-9 zusammengesetzt sind. Man kann sich auch andere Tokens vorstellen – bspw zeitbasierte oder Hashwerte über bestimmte Request-Parameter.
Unsere 10 Zeichen-Implementierung werden wir noch ersetzen, denn es nicht sichergestellt ist, dass 2 aufeinanderfolgende Tokens nicht zufällig gleich sind. Dann hätte der Zufallszahlengenerator ein Problem oder es wäre der sprichwörtliche 6er im Lotto – und genau das passiert, wenn man eine solche Implementierung Live schaltet 😉

5 Kommentare

    • Sicherlich. Jedoch hätte ich mir ein Beispiel ausdenken müssen, dass genau diesen Anwendungsfall widerspiegelt. Solche wirken oft an den Haaren herbeigezogen und daher gibt es nur diese abstrakte Version. Aber das Paper zu diesem Pattern ist verlinkt, das die Anwendung mit UML-Diagrammen untermalt.

  1. fand es jetzt eigentlich verständlich. Muss ja nicht alles mit Äpfeln und Birnen sein, als programmierer ist A1 oder B1 doch anschaulich genug 🙂

    Hatte zwar jetzt noch nicht den Fall, daß ein Ajaxrequest einen solch gearteten Rattenschwanz hinter sich her zieht, wird aber sicher früher oder später kommen, von daher habe ich den Artikel aufmerksam gelesen – ist ein interessanter Denkanstoß; in diesem Sinne, thx für die kurze Erläuterung!

    Antworten
  2. Ich finde die Idee gut und kann mir durchaus diverse Szenarien vorstellen.

    Zur Token-Problematik hätte ich einen Vorschlag:

    Man muss ja nicht immer jedes Rad neu erfinden und gerade in diesem Fall halte ich es für denkbar, Anleihen aus den Streamingprotokollen zu holen.
    Wenn man A, B und wie sie alle heißen, jeweils als Stream auffasst und das früher einmal gelernte RTP (http://de.wikipedia.org/wiki/Real-Time_Transport_Protocol) im Hinterkopf findet, fällt einem eventuell die Sequenznummer ein 😉

    Damit lassen sich zudem auch Paketverluste erkennen und vor allem auch Reihenfolge gewährleisten.

    Es besteht dann zwar nach wie vor die Problematik der Zufälligkeit, welche durch die inkrementelle Sequenz auch noch verschärft wird, sollte aber enorme Vorteile innerhalb des einzelnen Streams mit sich bringen.

    Antworten
  3. Eine Kollision bei einem String (a-zA-z0-9) von 10 Zeichen Länge dürfte sehr sehr viel unwahrscheinlicher sein, als ein 6er im Lotto…
    Solange die Tokens nicht endlos gültig sind, ist es vollkommen ausreichend.

    Antworten

Schreibe einen Kommentar

Pflichtfelder sind mit * markiert.