Graceful shutdown

Topics about the Software of Revolution Pi
Post Reply
RTI GWF
Posts: 3
Joined: 10 Mar 2025, 14:09

Graceful shutdown

Post by RTI GWF »

Hallo Zusammen

Ich entschuldige mich das die Frage ein wenig ausführlicher wird, aber für ein Verständnis benötige ich ein bisschen an Erklärung.

Ich möchte gerne verstehen, wie oder was der RevPI Commander an/mit dem laufenden Python Skript macht, wenn ein "SPS stop" gedrückt wird, oder besser noch auch ein Error während dem Ausführen zustande kommt?
Allgemein gesehen, geht es mir darum einen "sicheren" Shutdown auszuführen. D.h. zum Beispiel, alle Outputs auszuschalten und Subprozesse kontrolliert herunterzufahren, anstelle einfach mitten im Prozess zu "killen".

Das Setup ist wie auf dem Bild python_architecture.png. Das Ziel dabei ist verschiedene Threads laufen zu lassen um verschiedene Tasks unabhängig vom I/O loop auszuführen. Weil ich aber noch nicht herausgefunden habe, wie ich bei "SPS start" das Programm direkt in der virtuellen Umgebung starten kann, mache ich das über ein Launcher -Programm (run_main.py). Dieses startet main.py innerhalb der venv. über einen subprocess call.
Main.py erzeugt dann die Threads.

Nun zum Ablauf. Wenn dann "SPS stop" gedrückt wird, möchte ich gerne ein kontrolliertes herunterfahren auslösen. Das ist in etwa im Bild desired shutdown.png zu sehen.

So wie es jetzt aber anhand der logs im Commander aussieht, probiert der Commander die SPS zu stoppen, aber weil ich eine Verzögerung durch mein Herunterfahre probiere auszuführen, erzwingt der Commander den "kill" des Tasks? Kann man dies verhindern oder verzögern? Wie lösen andere ein kontrollieres Herunterfahren im Error-Fall?

Code: Select all

2025-03-10 14:03:17 [WARNING ] can not term plc program /var/lib/revpipyload/21.0203-ixion/run_main.py
2025-03-10 14:03:17 [WARNING ] killed plc program
+ mehr als Nebenfrage: Gibt es auch eine möglichkeit ein Skript direkt in der venv auszufüren, ohne dass ein run_main.py nötig ist?
Attachments
desired shutdown flow.png
python_architecture.png
User avatar
RevPiModIO
KUNBUS
Posts: 341
Joined: 20 Jan 2017, 08:44
Contact:

Re: Graceful shutdown

Post by RevPiModIO »

Hi RTI GWF!

Wenn beim RevPi Commander "SPS stop" geklickt wird, wird an dem Python Prozess das "SIGTERM (15)" Signal gesendet. Dies passiert auch, wenn der Dienst "revpipyload" beendet wird / oder das System herunterfährt.

Das "SIGTERM" Signal muss in Ihrem laufenden PLC-Programm verarbeitet werden, es müssen z.B. alle Threads beendet, alle Ausgänge in einen definierten Zustand und alles sonstige "Aufräumarbeiten" ausgeführt werden. Nachdem diese Aufgaben von dem Programm erledigt wurden, muss sich das Programm selber beenden.

Sollte das PLC-Programm nicht innerhalb eine definierten Zeit (Standardwert: 5 Sekunden) alles erledigt und sich beendet haben, wird das "SIGKILL (9)" Signal für den Prozess gesendet und das Programm einfach gestoppt. Dieser Wert kann aktuell leider nicht über den RevPi Commander verändert werden. Er muss über die Datei "/etc/revpipyload/revpipyload.conf" verändert werden, wenn 5 Sekunden nicht ausreichen. Dazu einfach "plcprogram_stop_timeout" auf einen höheren Wert setzen.

Die Unterscheidung ob das PLC-Programm erfolgreich oder fehlerhaft abgelaufen ist, wird von RevPiPyLoad über den Exit-Code entschieden. Gibt das Programm den Exit-Code 0 zurück, gibt es keinen Fehler. Sollte dieser ungleich 0 sein "exit(1)" gab es einen Fehler und RevPiPyLoad wird entsprechend der Einstellungen für einen Fehler das Programm neu starten.

Mit freundlichen Grüßen
Sven
python3-RevPiModIO - https://revpimodio.org/ || Der RevPi ist das Beste, was passieren konnte!
RTI GWF
Posts: 3
Joined: 10 Mar 2025, 14:09

Re: Graceful shutdown

Post by RTI GWF »

Hallo Sven

Ich danke dir für die Antwort und die Erklärung. Super es hilft sicherlich diesen Wert anpassen zu können :).

Unterdessen haben sich doch noch ein paar Folgefragen meinerseits aufgetan bei welchen du/ die Community ev. ebenfalls helfen könntet.

1. Wie in meinem Ablauf oben aufgezeigt benötige ich ein run_main.py um mein Programm in der Venv zu starten. Gibt es eine Möglichkeit das direkt zu machen, ohne den Umweg über diese Launcher-File? Also kann ich an einem Ort der PLC mitgeben, dass der Python Interpreter in der venv zu finden ist und ich so mein main.py direkt starten kann?

2. Auch zum Thema SW Architektur: Ich habe probiert mit der oben beschriebenem Aufbau eines eurer Tutorials auszuführen, also das Events im mainloop() (https://revpimodio.org/events-mit-dem-mainloop/). Dabei würde das im meinem «RevPi module thread» laufen lassen. Jetzt bekomme ich die Fehlermeldung das es nur im im main Thread möglich sein diese Funktionen auszuführen. Woran liegt das? Gibt es einen Workaround? Weil so wie ich das verstehe, müsste ich dann as RevPi Modul theoretisch im Launcher-File aufrufen um diese Funktion nutzen zu können, was nicht wirklich eine Option ist.

Code: Select all

ValueError: signal only works in main thread of the main interpreter
Leider habe ich dazu noch keine Lösung gefunden, auch noch nicht hier im Forum.

3. In revpipyload.conf definiert man das Workingdir und das PLC- Programm. Wird das workingdir automatisch den Systempfaden hinzugefügt? Momentan muss ich dies auch über das run_main.py File machen und frage mich gerade ob es helfen würde diesen nicht auf /var/lib/revpipyload, sondern direkt auf dem Projekt zu haben?

4. Allgemein geshen, bin ich noch im Prozess zu verstehen wie das RevPi aufgebaut ist und was mann alles eingermassen "save" ändern kann um auf die eigenen Bedürfnisse anzupassen. Gibt es neben dem revpipyload.conf noch andere wichtige config files von welchen man wissen müsste? Oder gibt es irgendwo einen Flow in welchem man die Zusammenhänge des RevPi und revpipyload ein wenig besser verstehen kann?

Danke nochmals für die Hilfe.
Grüsse
Raphael
Last edited by RTI GWF on 12 Mar 2025, 08:29, edited 1 time in total.
Post Reply