Watchdog / Heartbeat

Hallo Torben

Wir steuern mAirList auf unserm Sendeautomaten durch eine Steuersoftware (SOAP Schnittstelle) Diese Steuersoftware kontrolliert auch die Audiokreuzschiene / News-Übernahme sowie überwacht den Sendebetrieb (Steuerhardward) Wir laden zu jeder vollen Stunde bzw. nach den News die nächste Playlist. Sofern nun mAirList keine SOAP Befehle mehr bekommt, weil z.B. die Steuersoftware oder Steuerhardward abgestürzt ist, läuft mAirList nicht mehr weiter.

Wäre es denkbar, eine Art Watchdog, ins mAirList einzubauen. Dieser Watchdog zählt auf Null runter (z.B. 1x pro Minute). Bei Null wird eine Notification ausgelöst.
Der Watchdog sollte sich per Script zurück setzen lassen (z.B. 60min).

Was denkst Du?

Michel

Hast du dir schonmal die neuen Notification-Prozeduren OnTimer und OnExecuteCommand angesehen? Damit sollte sich das realisieren lassen. Einfach eine globale Variable nehmen, in der die Uhrzeit des letzten Befehls gespeichert wird. Du kannst dir dann einen Befehl “RESET TIMER” oder so definieren, der im OnExecuteCommand abgefangen wird, woraufhin die Zeit zurückgesetzt wird. Im OnTimer schaust du, wie lange seit der letzten Befehls-Zeit vergangen ist, und reagierst evtl. entsprechend.

Ich bin leider im Moment zeitlich knapp dran, daher kann ich dir in diesem Moment kein fertiges Script anbieten. Wenn ich helfen soll, musst du dich einige Tage gedulden.

Interessant. Werde die Befehle ausprobieren und mir versuchen ein Script zu schreiben. Das Resultat poste ich anschliessend.

Mal sehe was ich hinkriege.

Hast du dir schonmal die neuen Notification-Prozeduren OnTimer und OnExecuteCommand angesehen?
  • Kann leider OnTimer nicht in der mAirListScript.chm (Version 13.09.2007) finden.

Ich sehe gerade, das ist in der v2.1.38 noch gar nicht drin, nur im aktuellen Snapshot.

Ich hatte gerade einige Minuten Zeit und habe dir folgendes Script zusammengebastelt:

[code]procedure OnStartup;
begin
SetTimerInterval(60000); // nach 60000ms = 1 Minute benachrichtigen
EnableTimer;
end;

procedure OnTimer;
begin
SystemLog(‘no heartbeat received! urgent action!’);
end;

procedure OnExecuteCommand(Command: string);
begin
if Command = ‘HEARTBEAT’ then begin
// Timer zurücksetzen
DisableTimer;
EnableTimer;
end;
end;

begin
end.[/code]

Im OnStartup wird der Timer mit dem gewünschten Intervall intialisiert und aktiviert. Wenn der Befehl ‘HEARTBEAT’ empfangen wird (kannst du per SOAP, als Hotkey oder wie auch immer schicken), wird der Timer aus- und wieder eingeschaltet, wodurch er zurückgesetzt wird. Wenn aber nach der eingestellten Zeit kein Heartbeat empfangen wurde, wird OnTimer aufgerufen, wo man dann den Notfallplan aktivieren kann.

Danke, das Script läuft.

Frage 1: Mit welchem Befehl kann ich den aktuellen Timer auslesen?

Frage 2: Kannst Du mir für den Heardbeat ein Screen Object machen?

Michel

zu 1: Geht meines Wissens nicht. Wenn du wissen willst, wieviel Zeit seit dem letzten Heartbeat vergangen ist, musst du das in einer globalen Variable speichern.

zu 2: Das verstehe ich nicht ganz.

Zu 2:

Das Screen Object, soll wie der Countdown, die aktuelle Timerzeit in min. herunter zählen.

Michel

Ach so. Nein, das geht nicht.

Okay, wäre nett gewesen, so kann ich eben nicht kontrollieren, ob der Heartbeat funktioniert. Aber alles in allem eine geniale Sache.

Vielleicht etwas für den Ordner Script von mAirList.

Michel

Man könnte das Script noch folgendermaßen variieren:

Man definiert eine globale Variable vom Typ “TDateTime”, die im OnStartup mit der aktuellen Uhrzeit (“now”) initialisiert wird. Ebenso wird die Variable immer dann auf die aktuelle Uhrzeit gesetzt, wenn ein Heartbeat empfangen wird.

Den Timer definiert man nun um, auf ca. 1 Minute oder weniger. Im OnTimer wird überprüft, wie groß die Differenz zwischen der gespeicherten und der aktuellen Uhrzeit ist, und ggf. eine Aktion ausgelöst.

Weiterhin kannst du dir einen zweiten Befehl definieren, der im OnExecuteCommand abgefangen wird und die aktuelle Differenz in das System Log schreibt.

Ich versuche mal, das Script (ungetestet) zusammen zu kriegen:

[code]var LastHeartbeat: TDateTime;

procedure OnStartup;
begin
LastHeartbeat := now;
SetTimerInterval(1000);
EnableTimer;
end;

procedure OnTimer;
begin
if now - LastHeartbeat > (1/24/60) then begin
SystemLog(‘ACTION!’);
end;
end;

procedure OnExecuteCommand(Command: string);
begin
if Command = ‘HEARTBEAT’ then
LastHeartbeat := now
else if Command = ‘SHOW HEARTBEAT’ then
SystemLog('Letzter Heartbeat war am ’ + FormatDateTime(‘hh:nn:ss’, LastHeartbeat));
end;

begin
end.[/code]

Die Zahl 1/24/60 steht hier für eine Minute, gemäß der Definition von TDateTime.

Ich bekomme jede Sekunde eine ACTION! Es sieht so aus, als folgender Code nicht funktioniert:

if now - LastHeartbeat > (1/24/60) then begin

Schon sofort einmal pro Sekunde, oder erst nach einer Minute zum ersten Mal und danach einmal pro Sekunde?

Wenn nur letzteres, dann reicht es, auch im OnTimer die Zeit wieder zurückzusetzten (LastHeartbeat := now).

Schon sofort einmal pro Sekunde

Stimmt, das Pascal Script mag den Bruch nicht. Wenn man es als Dezimalzahl hinschreibt, geht es: 0,000694

Den Zähler solltest du aber trotzdem zurücksetzten, damit das Event nicht nach einer Sekunde sofort wieder losschießt.

0,000694 gibt bei mir leider einen Error. Mit 1 läuft das Script

Nimm als Dezimaltrennzeichen einen Punkt statt einem Komma (englische Schreibweise).

Und siehe da … heartbeat.mls loaded :wink: Jetzt teste ich mal das Script