Der ADMIN 05/13 wirft einen Blick auf die frei verfügbaren Cloud-Frameworks von Eucalyptus über OpenNebula bis OpenStack. Gute Aussichten für skalierbare ... (mehr)

Fortlaufende Zähler

Jede Nachricht besitzt eine ID, die in aufsteigender Reihenfolge von der Datenbank beim »INSERT« erzeugt (Datentyp »SERIAL« ) wird. Die Anwendung geht davon aus, dass dieser Zähler nicht überlaufen kann. Beim Betreten eines Chat-Raumes werden die Nachrichten und deren IDs übertragen. Der Browser merkt sich die höchsten IDs. Diese wird der Listen-Aktion als Parameter mitgegeben. Diese Aktion kann also interpretiert werden als: "Gib mir alle Nachrichten im Raum mit einer ID größer als N oder warte auf neue Nachrichten, falls es keine solchen gibt!"

Listing  7 zeigt die relevanten Teile der Listen-Aktion. Nach Prüfung der Parameter wird in Zeile  33 die SQL-Operation

Listing 7

Die Listen-Aktion

 

LISTEN r_RAUMNAME

ausgeführt. Damit hat das Programm sich als Empfänger für Notifikationen in dem Raum registriert. »reply_messages« in Zeile  36 sucht nach neuen Nachrichten und schickt sie dem Browser. Die Anzahl wird zurückgegeben. Liefert die Funktion 0, also keine neuen Nachrichten, wird »wait_for_notification« aufgerufen. Diese Funktion ist ähnlich zu »query« aufgebaut. Sie kehrt in zwei Fällen zurück: wenn Notifikationen eingetroffen sind und wenn der Watcher in Zeile  10 aktiviert wurde. Der Event-Loop ist wieder mit einer Condition-Variable in Zeile  19 implementiert.

Der verschwundene Browser

Neu an der Funktion sind eigentlich nur die Zeilen 7 bis 13. Hier wird die TCP-Verbindung zum Browser überwacht. Das ist nötig, denn im Prinzip kann die Aktion unendlich lange auf eine Notifikation warten. Wenn der Benutzer nun das Fenster schließt oder den Rechner ausschaltet, muss das Skript das merken, sonst werden die verwendeten Ressourcen nicht freigegeben.

In Zeile  7 wird dazu zunächst der Dateideskriptor der Verbindung zum Browser ermittelt. Der Watcher wartet dann, dass der Socket lesbar wird. Das kann zwei Dinge bedeuten: Entweder ist die nächste Anfrage schon in der Pipeline oder es kann ein End-of-File gelesen werden. HTTP/1.1 erlaubt zwar, Folge-Anfragen in einen Socket zu schreiben, ohne auf das Resultat der aktuellen Anfrage zu warten, die Chat-Anwendung macht das aber nicht.

Wenn der Socket lesbar wird, kann das also nur eines bedeuten: Der Browser hat die Verbindung geschlossen. »wait_for_notification« gibt daraufhin in Zeile  20 die leere Liste zurück. Das führt in Zeile  37 zum Beenden der Anfrage mit dem HTTP-Code 500. Hier könnte man einen beliebigen Code benutzen, der nur in der Logdatei erscheint. Der Browser ist zu diesem Zeitpunkt schon verschwunden.

Die Query-Funktion macht recht viel Wind um Signale und Timeouts. Müsste »wait_for_notification« nicht auch darauf achten? Ein Timeout wäre möglicherweise sinnvoll, wenn man sich nicht darauf verlassen kann, dass das Schließen der TCP-Verbindung seitens des Browsers auch wirklich bemerkt wird. Signale werden von »query« nur abgefangen, um beim Stoppen des Webservers länger dauernde Datenbankabfragen zu beenden. Während das Programm auf Notifikationen wartet, läuft aber keine Abfrage. Hier Arbeit zu investieren, hat also keinen Sinn. Es wäre jedoch wahrscheinlich sinnvoll, die Prüfung auf den verschwundenen Browser auch in die Query-Funktion zu übernehmen.

Ähnliche Artikel

comments powered by Disqus
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2023