Hilfe gesucht: Automatischer Restart nach Crash

  • Hallo zusammen,


    ich bin JavaScript-Neuling und habe eine Applikation geschrieben, die aus einer HTML-Seite besteht und mehrere JavaScript-Komponenten einbettet, darunter JQuery- und Json-Skripte sowie ein API zu einem KNX-System zur Haus-Automatisierung. Diese drei stammen von dem Hersteller des KNX-Gateways und ich verstehe den Code nur teilweise. Der Zugriff aus meinem Skript, das Jalousien, Rolläden, Schalter und Lampen steuert und Komponenten einer Alarmanlage überwacht, erfolgt über Callback-Funktionen.

    Alles funktioniert scheinbar einwandfrei, doch nicht im Dauerbetrieb. Nach einigen Stunden, manchmal nach einigen Tagen, stürzt die App ab. Ruft man die Seite im Browser neu auf, läuft alles wieder für einige Zeit.

    Der Browser läuft ohne Bildschirm auf einem alten Mac mini unter MacOS 10.11.6 (EL Capitan), auf den ich über VNC zugreife. Ich habe neben Firefox auch Safari und Chrome probiert, ohne besseres Ergebnis. Mit den eingebauten Debuggern konnte ich keinen Fehler finden.

    Meine Frage: Gibt es eine Möglichkeit, das Ganze zu überwachen und bei Crash automatisch neu zu starten?

    Chris

  • Zitat

    Nach einigen Stunden, manchmal nach einigen Tagen, stürzt die App ab. Ruft man die Seite im Browser neu auf, läuft alles wieder für einige Zeit.

    Da frage ich mich, ob da vielleicht irgend wo ein Speicherleck vorhanden ist, wo immer mehr Speicher angefordert wird. Oder ein Stackoverflow, dass eine Funktion rekursiv aufgerufen wird. Poste doch mal dieses Javascript, wenn es nicht zu umfangreich ist.


    Wie man einen Neustart hinkriegen kann, weiß ich auf Anhieb nicht. Müsste man wahrscheinlich auf Betriebssystemebene machen, den Prozess überwachen und den Browser neu starten, wenn er nicht mehr da ist.


    Besser erst Mal versuchen, das Problem an der Wurzel zu lösen.


    Edit: Was heißt "stürzt ab"? Nur das Tab, wo die Seite läuft oder der Browser insgesamt? Sind irgend welche Fehlermeldungen sichtbar?

    Dieser Beitrag wurde bereits 2 Mal editiert, zuletzt von Sempervivum ()

  • Danke für die Antwort. Es sind vier Scripts, davon drei nicht von mir, und sie sind sehr umfangreich. Der Browser stürzt nicht ab, die Seite "lebt" noch (die Uhrzeitanzeige läuft) und reagiert sogar noch auf einen einzigen Klick, danach nicht mehr. Die im Hintergrund laufenden js-Routinen, die u. a. auf die Bewegungsmelder reagieren, Lichtautomaten und die Alarmanlage darstellen, funktionieren nicht mehr.

  • Wenn es nicht zu umfangreich ist, dann poste das Skript, das Du gemacht hast. Ich erinnere mich an Code wo ein Eventlistener im Callback eines anderen registriert wurde. Dann werden es mit jedem Klick immer mehr und mehr. Kann natürlich auch etwas anderes sein.


    Wenn nur die betr. Seite abstürzt, könnte man wahrscheinlich auch einen Neustart hinbekommen: Die Seite mit window.open öffnen und Lebenszeichen an die öffnende Seite senden lassen. Bleiben diese aus, kann man davon ausgehen, dass die Seite abgestürzt ist, sie schließen und neu öffnen.

  • Ich habe jetzt erstmal einen Eventlistener "error" hinzugefügt und warte mal ab, ob ich eine brauchbare Meldung kriege. Vielen Dank einstweilen!

  • Wenn nur die betr. Seite abstürzt, könnte man wahrscheinlich auch einen Neustart hinbekommen: Die Seite mit window.open öffnen und Lebenszeichen an die öffnende Seite senden lassen. Bleiben diese aus, kann man davon ausgehen, dass die Seite abgestürzt ist, sie schließen und neu öffnen.


    Lebenszeichen senden? Wie kann man das machen? (Ich bin Anfänger.) Kannst du mir ein Code-Beispiel geben?

  • Ich habe da mal eine Demo gemacht.

    Du brauchst eine Masterseite und dort dieses Javascript:

    Dieses öffnet die Slaveseite. Dort laufen dann all deine Javascripts und zusätzlich dieses:

    Code
    1. const intv = 1000;
    2. // Send lifesign to master periodically:
    3. setInterval(() => {
    4. // opener is the page that has opened this one,
    5. // i. e. the master page.
    6. // We call the function supervise over there:
    7. opener.supervise();
    8. console.log('livesign sent');
    9. }, intv);

    So weit getestet, man muss jedoch unbedingt für die Masterseite den Popupblocker ausschalten.


    Offene Frage: Du schriebst, dass die Seite nicht komplett abstürzt, sondern dass einige Funktionen (Uhrzeitanzeige) noch gehen. Wenn das auch für das JS für das Senden der Lebenszeichen zutrifft haben wir zunächst mal schlechte Karten.

  • Tut mir Leid, das vergaß ich ganz: Weil das Popup durch meinen Browser blockiert wurde, hatte ich einen Button eingeführt, um den Slave zu öffnen. Das war auch zunächst erfolgreich aber nützte nichts, wenn ich später beim Ausfall des Slave das Fenster durch das Skript neu öffnen wollte. Das ging dann nur, wenn ich den Popup-Blocker ausschaltete. Damit war dann die Notwendigkeit für den Button entfallen.

    Reduziere das Skript auf dieses:

    Code
    1. const intv = 1000;
    2. let win;
    3. // Open slave when button is clicked:
    4. // document.querySelector('button').addEventListener('click', event => {
    5. win = window.open('slave.html');
    6. // });
    7. let timer;
    8. // usw. wie bisher
  • Hatte ich schon gemacht. Jetzt zeigt die Konsole bei Slave

    Uncaught DOMException: Permission denied to access property "supervise" on cross-origin object

  • Dann werden wir jetzt offenbar mit den Problemen der SOP konfrontiert: Beide Seiten müssen auf der selben Domain liegen und über einen Webserver ausgeliefert werden. Ich vermute, Du rufst die Masterseite bei deinem Test ohne Webserver z. B. durch Doppelklick auf?

  • Ja, durch Doppelklick. Beide Dateien liegen auf dem Desktop. Ich habe geschrieben

    win = window.open('file:///Users/cp/Desktop/Slave.html');

  • Um da schnell weiter zu kommen, schlage ich vor, dass Du beide Dateien auf deinen Webspace hoch lädst. Es gibt natürlich auch lokale Webserver wie XAMPP, die das Testen sehr erleichtern.

  • Gibt es keinen anderen Weg? Mein Skript zur Hausautomatisierung läuft ebenso lokal. Da ist kein Webserver im Spiel.

  • Hm, das wäre natürlich unangenehm, wenn Du nur wegen dieser Kleinigkeit XAMPP installieren müsstest. Man kann eine Seite auch für Cross-Domain-Access frei geben, aber das erfordert ebenfalls einen Webserver. Wenn wir die Slave-Seite in einem iFrame anzeigen bekommen wir die selben Probleme wenn Master und Slave kommunizieren sollen. Ich erinnere da noch eine andere Möglichkeit, muss nachsehen, ob ich es wiederfinde ...

  • Das Senden von Nachrichten vom Slave zum Master funktioniert mit postMessage auch mit dem file-Protokoll, d. h. wenn man die Seite mit Doppelklick aufruft.

    Master-Skript:

    Slave-Skript:

    Code
    1. const intv = 1000;
    2. setInterval(() => {
    3. // Send alive message to opener:
    4. opener.postMessage('alive', '*');
    5. console.log('livesign sent');
    6. }, intv);

    Die schlechte Nachricht: Es ist mir nicht gelungen, den Popup-Blocker nur für diese eine Seite auszuschalten sondern musste es global tun. Lag wohl am file-Protokoll.