Ich kenne was, was Du nicht kennst: Later

Tales from the Web side  –  1 Kommentare

Ein interessantes Modul für das Definieren von Cron-Jobs oder ganz allgemein für das zeitgesteuerte Ausführen bestimmter Aufgaben ist Later. Es lässt sich mit Node.js und auch im Browser einsetzen und benötigt dabei keine Datenbank.

"Ich kenne was, was Du nicht kennst"

... ist eine gemeinsame Serie von Golo Roden und Philip Ackermann, in der die beiden regelmäßig Module für JavaScript und Node.js vorstellen.

Module für das Definieren von Cron-Jobs oder ganz allgemein für das zeitgesteuerte Ausführen bestimmter Aufgaben (Tasks) gibt es für Node.js recht viele: node-schedule, node-cron oder agenda beispielsweise, um nur einige wenige zu nennen. Ein interessantes Modul in dieser Kategorie ist das Modul Later, das sowohl unter Node.js als auch im Browser eingesetzt werden kann und dabei ohne eine Datenbank auskommt (im Gegensatz zu beispielsweise dem Modul agenda, welches ein installiertes MongoDB voraussetzt). Zudem verfügt das Modul über eine recht einfach zu erlernende und bedienende API.

Einrichtung

Möchte man das Modul unter Node.js verwenden, kann man es über den Node.js Package Manager mit dem Befehl npm install later installieren. Strebt man dagegen eine Verwendung in einer Browser-Umgebung an, lädt man es über bower install later entsprechend als Abhängigkeit ins aktuelle Projekt herunter. Unter Node.js wird das Modul wie gewohnt über den Befehl require('later') eingebunden, innerhalb eines HTML-Dokuments die entsprechende Bibliotheksdatei über das <script>-Element.

// Einbinden unter Node.js
let later = require('later');

// Einbinden im Browser
<script src="bower_componets/later/later.min.js" type="text/javascript"></script>
Definition von Ausführungsplänen

Das Nette an dem Modul ist, dass sich die Planung einzelner Tasks bzw. der damit verbundenen Definition von Ausführungsplänen auf verschiedene Arten vornehmen lässt. Entsprechend dazu bietet das Modul drei verschiedene Parsermethoden an, die über das Objekt later.parse bereitgestellt werden.

Wer die Cron-Syntax bevorzugt, kann beispielsweise die Methode later.parse.cron() verwenden, welcher man einfach einen entsprechenden Cron-Ausdruck übergibt. Um beispielsweise eine Task zu definieren, die jeden Tag um 8.30 Uhr morgens ausgeführt wird, würde man folgenden Befehl verwenden:

let schedule = later.parse.cron('30 8 ? * *');

(Anmerkung für alle, die mit der Cron-Syntax nicht so vertraut sind: Die Positionen im String stehen für (1) Minute, (2) Stunde, (3) Tag, (4) Monat und (5) Wochentag. Über weitere Zeichen wie dem Komma (,), dem Bindestrich (-) und dem Backslash (/) ist es zudem möglich, jeweils mehrere Zeitangaben, einen Zeitraum oder eine Periode anzugeben).

Wem das alles zu kryptisch ist, dem bietet das Modul zwei interessante Alternativen. Obiger Ausführungsplan ließe sich nämlich unter Verwendung der Methode later.parse.text() über einen sprechenden Text eingeben:

let schedule = later.parse.text('at 8:30 am');

Auf diese Weise lassen sich auch komplexere Ausführungspläne wie folgender definieren:

let schedule = later.parse.text('at 8:30 am also at 5:30pm 
except on Tuesday');

Das ist zwar schön zu lesen, aber schlecht zu merken. Zumindest benötigt man einige Zeit, um sich die zur Verfügung stehenden Textbausteine zu verinnerlichen. Hier kommt die dritte und letzte Alternative ins Spiel, denn diese definiert eine Fluent API (also eine sprechende, lesbare API), mit der eine Verkettung einzelner Methodenaufrufe möglich wird, was wiederum zu einem sehr lesbaren Code führt. Gegenüber der rein textuellen Eingabe von eben haben diese aneinander geketteten Methodenaufrufe den Vorteil, dass man sie sich als Entwickler – entsprechenden IDE- bzw. Editorsupport vorausgesetzt – nicht unbedingt merken muss. Der einfache Ausführungsplan von eben würde nun über die Methode later.parse.recur() wie folgt definiert:

let schedule = later.parse.recur().on(8,30).hour();

Bei komplexeren Ausdrücken wird noch deutlicher, wie übersichtlich diese API ist:

let schedule = later.parse.recur()
.every(2).hour() // alle zwei Stunden
.first().dayOfMonth() // am ersten Tag eines Monats
.and() // und
.on(8, 20).hour() // zwischen 8:00 und 20:00
.last().dayOfMonth() // am letzten Tag eines Monats
.except().on(5).month(); // außer im Mai

Alle drei gezeigten Möglichkeiten erzeugen jeweils ein Objekt, welches den entsprechenden Ausführungsplan für eine Task enthält (in den Beispielen die Variable schedule). Letztendlich handelt es sich dabei um einfache Objekte (man könnte sagen POJOs), die man prinzipiell auch manuell erzeugen könnte – ohne auf eine der gezeigten Möglichkeiten zurückzugreifen.

Tasks starten

Wie auch immer man also zu einem Schedule-Objekt kommt: als nächstes gilt es, eine Task auch zu starten. Dazu stellt das Modul zwei Methoden zur Verfügung: later.setTimeout() zum einmaligen Ausführen einer Task sowie later.setInterval() für das wiederholte Ausführen einer Task. Beide Methoden erwarten als Parameter die entsprechende Task (in Form einer Funktion) sowie das eben definierte Schedule-Objekt:

// Einmalige Ausführung
function logTime() {
console.log(new Date());
}
let timerTimeout = later.setTimeout(logTime, schedule);

// Wiederholte Ausführung
let timerInterval = later.setInterval(logTime, schedule);

Über das jeweils zurückgegebene Timer-Objekt lässt sich durch Aufruf der Methode clear() ein Ausführungsplan auch wieder abbrechen.

Fazit

Das Modul Later ermöglicht das zeitgesteuerte Ausführen von Tasks. Ausführungspläne können dabei entweder über Cron-Ausdrücke, über sprechende Textpassagen oder über eine relativ einfach zu bedienende Fluent API erstellt werden. Vorteile gegenüber anderen ähnlichen Modulen sind zum einen, dass das Modul sowohl unter Node.js als auch im Browser verwendet werden kann und zum anderen, dass keine Datenbank als Abhängigkeit vorausgesetzt wird.