Wissen

KNOW-HOW FÜR FORTSCHRITT

Ein Vorteil von node.js ist die Asynchronität. Leider kann diese äußerst positive Eigenschaft dem Entwickler in einigen Spezialfällen starkes Kopfzerbrechen bereiten. Als Beispiel haben wir eine API geschrieben, die Anfragen entgegennimmt und Daten aus einer Datenbank ausliest und schreibt bzw. löscht. Zusätzlich wird auf dem Dateisystem gearbeitet und Dateien werden kopiert und archiviert. Da es sich um sensible Daten handelt, sollte beim Archivieren oder auch beim Kopieren von den Dateien nichts schief gehen. Kommen nun zwei Anfragen an, die den länger dauernden Prozess anstoßen, überschneiden sich diese und können dadurch möglicherweise nicht erfolgreich ausgeführt werden.

Wie lässt sich nun ein Codeblock oder etwa ein API-Endpunkt für weitere Anfragen blockieren?

Man könnte erahnen, dass an dieser Stelle ein Locking-Mechanismus bzw. im übertragbaren Sinne Semaphoren die Lösung wäre.

Hier setzen die node-Module von Ian Babrou an. Sein Ansatz besteht aus zwei Modulen. Das erste Modul befasst sich mit einem eigenen Locking Server und das zweite mit der Implementierung des Locks an sich.

Locking Server

Der Lock Server namens „locker“ ist eine eigene kleine node.js-App, die einzelne Tasks verwaltet und den Zugriff steuert.

Es besteht natürlich die Möglichkeit den Server in der eigenen Anwendung zu integrieren. Um die Ausführung der eigenen App jedoch nicht zu behindern, lässt sich dieser Teil auch auslagern.

(function() {
    var Locker = require("locker-server"),
        locker = new Locker();

    locker.listen(4545);
})();

Locking Client

Der zweite Teil ist der Locker Client. Nach dem Laden des Modules kann um einen eigenen Codeblock, beispielsweise dem Inhalt einer Funktion eines API Endpunktes, ein Locking gebaut werden. Dies geschieht über die Funktion „locked“, welche vier Parameter erwartet. Als erstes sollte ein vernünftiger und eindeutiger Name vergeben werden. Danach kommen zwei Zeitangaben in Millisekunden. Die erste ist die Wartezeit um selbst den Task (das Lock) zu bekommen und die zweite ist ein Timeout, wie lange die Ausführung des Tasks maximal dauern darf. Der letzte Parameter ist eine Callback-Funktion, die ausgeführt wird, wenn man das Lock erhalten hat. Zusätzlich bietet Locker grundlegende Events, um auf verschiedene Zustände des Locker Servers zu reagieren.

var Locker = require("locker"), // Locker laden
    locker = new Locker(4545, "127.0.0.1"); // Mit Locker Server verbinden

locker.on("reset", function() { // Verbindung wurde zurückgesetzt
    console.log("Reset happened (is server running?)");
});

locker.on("error", function (error) { // Fehlerfall
    console.log("Catched error:", error);
});

//            task    wait  max   callback
locker.locked("five", 2000, 3000, function (error, callback) {
    if (error) {
        // Lock fehlgeschlagen
        callback(error);
        return;
    }

    // Lock freigeben ohne Fehler
    callback(undefined, {well: "done"});
});

Fazit

Wer auf der Suche nach einer schnellen und eleganten Lösung eines Locking-Mechanismus ist, liegt bei Locker nicht falsch. Schnell installiert und leicht einsetzbar. Gerade wenn man einen kleinen Blick in eine – hoffentlich – nicht allzu ferne Zukunft wirft und das node.js-Clustering-Modul endlich als stabil gekennzeichnet wird, ist der Ansatz von Ian Babrou gold wert.

Wir freuen uns über eine Bewertung, um ein Feedback zu erhalten:

Es gibt noch keine Bewertungen.