Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Hardwareinitialisierung mittels statischer PHP Klasse

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • #16
    Läuft das eine Script also dauerhaft als "Dämon"?
    Dann wäre die Lösung wohl mit den vorhandenen Mitteln das Einfachste.
    Ich setze das in ähnlicher Form seit Jahren für Cron-Scripte ein, die auch gerne mal länger laufen und sich so mit dem nächsten AUfruf überschneiden könnten.
    Damit das nicht passiert wird auch ein Lockfile generiert und erst nach Abarbeitung wieder freigegeben/gelöscht.
    Das klappt mit mehreren tausend Transaktionen pro Tag seit ~3 Jahren ohne jegliche Probleme.
    VokeIT GmbH & Co. KG - VokeIT-oss @ github

    Kommentar


    • #17
      Zitat von G.Schuster Beitrag anzeigen
      Läuft das eine Script also dauerhaft als "Dämon"?
      Dann wäre die Lösung wohl mit den vorhandenen Mitteln das Einfachste.
      Ich setze das in ähnlicher Form seit Jahren für Cron-Scripte ein, die auch gerne mal länger laufen und sich so mit dem nächsten AUfruf überschneiden könnten.
      Damit das nicht passiert wird auch ein Lockfile generiert und erst nach Abarbeitung wieder freigegeben/gelöscht.
      Das klappt mit mehreren tausend Transaktionen pro Tag seit ~3 Jahren ohne jegliche Probleme.
      Ja, die Scripte laufen normalerweise rund um die Uhr.
      Ich werde das mit dem Lockfile ausprobieren - bin heute nur nicht dazu gekommen.

      Wenn Du gute Erfahrungen damit gemacht hast, sollte es doch bei mir auch funktionieren.
      Zumal es sich bei mir nur um den Startvorgang handelt. Wenn der erst einmal erfolgreich verlaufen ist, benötige ich ja das Lockfile gar nicht mehr.

      Jedenfalls vielen Dank für Eure Antworten.

      Gruß
      Jörg
      www.photonensammler.de

      Kommentar


      • #18
        Und was machst du, wenn mal eines deiner Scripte neu startet?
        Ich würd da schon mit einem dauerhaften Lockfile arbeiten.
        So lange das eine Script, das den Lock hält, noch läuft braucht da kein anderes neu zu initialisieren.

        Wenn die Scripte dauerhaft laufen wäre es auch eine Idee, das noch um einen "Restart" zu ergänzen.
        Soll heißen, wenn das Lock-Script abstürzt und das nächste Script einen neuen Lock setzt könntest du noch ein Triggerfile "touchen", das, wenn vorhanden, alle anderen Scripte dazu animiert, sich zu beenden und neu zu starten, um auf die neu initialisierte Verbindung zu reagieren (oder was da halt nötig ist).
        VokeIT GmbH & Co. KG - VokeIT-oss @ github

        Kommentar


        • #19
          Zusätzlich könntest auch noch einen Heartbeat in die Datei schreiben.

          Das ist ein einfacher Zeitstempel, den der 'Halter' der Datei in definierten Abständen aktualisiert. Somit könnten andere Prozesse nachschauen ob noch alles in Ordnung ist.

          Kommentar


          • #20
            Zitat von G.Schuster Beitrag anzeigen
            Und was machst du, wenn mal eines deiner Scripte neu startet?
            Ich würd da schon mit einem dauerhaften Lockfile arbeiten.
            So lange das eine Script, das den Lock hält, noch läuft braucht da kein anderes neu zu initialisieren.

            Wenn die Scripte dauerhaft laufen wäre es auch eine Idee, das noch um einen "Restart" zu ergänzen.
            Soll heißen, wenn das Lock-Script abstürzt und das nächste Script einen neuen Lock setzt könntest du noch ein Triggerfile "touchen", das, wenn vorhanden, alle anderen Scripte dazu animiert, sich zu beenden und neu zu starten, um auf die neu initialisierte Verbindung zu reagieren (oder was da halt nötig ist).
            Du hast Recht, das Lockfile wird vom zuerst gestarteten Script während der ganzen Laufzeit gehalten. Dieses Script initialisiert auch die Hardware einmalig.
            Danach gestartete Scripte - egal zu welcher Zeit sie starten - finden immer die (blond)gelockte Datei und nehmen deshalb keine Initialisierung vor.
            Beachte bitte dabei, dass es nur um den Start geht, bei dem ein Init erforderlich ist, während der normalen Laufzeit tritt dieser Zustand nicht mehr auf.

            Sollte eines der später gestarteten Scripte abstürzen und neu gestartet werden müssen, ist die Lockdatei immer noch da und alles läuft wieder wie gehabt weiter.

            Wenn natürlich das Script, dass den Lock hält, wegen Absturz (o.ä.)neu gestartet wird, muss sowieso alles andere neu gestartet werden. Für diesen Fall muss ich mir noch etwas einfallen lassen.

            Allerdings ist ein Absturz bei dem Script, dass ich zuerst starten werde, relativ unwahrscheinlich. Der Code ist nicht sonderlich kompliziert und wenig fehleranfällig.

            Gruß
            Jörg
            www.photonensammler.de

            Kommentar


            • #21
              Darf man fragen um was für ein Projekt es sich handelt?

              Kommentar


              • #22
                Zitat von MasterD Beitrag anzeigen
                Darf man fragen um was für ein Projekt es sich handelt?
                Etwas ähnliches läuft bei mir schon fast ein Jahr unter http://photonensammler.homedns.org/A...?glaetten=true
                Die Seite, besonders die Übersicht am Seitenende, sind nicht mehr ganz aktuell. Es wurden schon weitere Funktionen hinzugefügt, die weitere Schaltvorgänge auslösen, aus Platzmangel auf der Seite und aus Faulheit dort aber nicht eingezeichnet sind.
                Bei dieser Hardware sind mir jetzt aber die Ein- und Ausgänge "ausgegangen" womit ich nicht mehr erweiteren kann.
                Deshalb habe ich das Projekt mit völlig neuer eigener Hardware neu aufgelegt, womit ich jetzt 32 Analogeingänge und je 16 Digitale Ein- und Ausgänge habe.

                Die Software dazu wird auch neu erstellt.
                Vorher war alles in einem einzigen PHP-Script zusammengefasst. Jetzt wird es modular aufgebaut (deshalb läuft es auch mit merhreren Scripten).
                Im Groben beschrieben wird es etwa so funktionieren:
                - ein Script fragt alle Eingänge (Analog und Digital) ab und speichert die Werte in einer Mysql-Datenbank (dieses Script wird auch als erstes gestartet)
                - Zwei weitere Scripte kümmern sich um die Ausgaben zu einem angeschlossenen 2zeiligen LCD-Display, das z.B. anzeigt, ob und mit welcher Abtastrate die Messung läuft. Jede LCD-Zeile hat ihr eigenes Script weil die Ausgaben nicht synchron sind
                - ein weiters Script liest die Messwerte aus der Datenbank und löst bei Bedarf Schalthandlungen an den Digitalausgängen aus
                ....und weitere Scripte könnten bei Bedarf folgen, da werde ich sehen, was ich benötige wenn der Rest erst einmal funktioniert.

                Der modulare Aufbau hat den Vorteil, dass ich einfach bei Bedarf die Software erweitern kann, ohne die bestehenden, schon funktionierenden Programme ändern zu müssen. Die Daten werden einfach aus der Datenbank geholt, mit irgend welchen Vorgaben verglichen und dann reagiert.

                In dieser Form (mit mehreren Scripten) habe ich aber noch nie programmiert und bin deshalb jetzt auf diese "Stolperstellen" gestoßen, bei denen ich mal Eure Hilfe brauchte. Ich habe PHP erst vor ca. 2 Jahren gelernt und bin deshalb nicht gerade der Profi. Das Projekt auf meiner Seite war mein erstes größeres PHP-Projekt.


                Gruß
                Jörg
                www.photonensammler.de

                Kommentar


                • #23
                  Hallo,

                  es funktioniert nicht , hat jemand eine bessere Idee????

                  Die Struktur der Klasse für die Hardware sieht in etwa so aus:


                  PHP-Code:
                  <?php
                    
                  class controller{
                      
                  //.....irgendwelche statischen Funktionen

                      
                  public static function init(){
                        
                  //prüfen, ob Lockfile gelockt ist
                        //wenn nicht, Datei locken und die Hardware vollständig initialisieren
                        //wenn ja, nur ein paar Klassenvariablen belegen ohne die Hardware neu zu initialisieren
                      
                  }
                    }

                  controller.init(); //Das ist der constructor-Ersatz für die statische Klasse
                  ?>
                  Die (mehreren) Scripte, die die Klasse benutzen dazu sehen etwa so aus:

                  PHP-Code:
                  <?php
                    
                  include_once('controller.php');
                    
                  // ab hier dann programmcode
                  ?>
                  Das Locking von Dateien funktioniert auf Scriptebene (siehe meine zwei Beispiele ein paar Beiträge weiter oben).

                  Wenn ich es aber in Klassen benutze, geht es nicht.

                  Bei jedem include_once('controller.php'); wird der constructor-Ersatz init(); ausgeführt.
                  Allerdings ist der Lock auf die Datei beim Starten jedes weiteren Scripts nicht mehr vorhanden weil der PHP-Interpreter das init() der Klasse offensichtlich als eigenen Script behandelt, der nach Abarbeitung für den Interpreter beendet ist (obwohl das Script, das das include_once() ausgeführt hat, noch läuft) ????
                  Damit wird der Lock auf die Datei nach Beendigung des init() der Klasse aufgehoben.

                  komplizierte Beschreibung, hoffentlich hat jemand von Euch die Nerven, das auch noch zu verstehen

                  Jetzt weiß ich nicht mehr weiter.

                  Gruß
                  Jörg
                  www.photonensammler.de

                  Kommentar


                  • #24
                    Das liegt dann wohl an einem Fehler in deinem Klassendesign.

                    Um den zzu erkennen musst du wohl mal die komplette klasse inkl. deren Aufruf posten...

                    Kommentar


                    • #25
                      controller.init();
                      ???
                      controller::init() meinst du wohl.

                      Schließt du in der init() das Lockfile wieder?
                      Das wäre sowieso der interessantere Code gewesen, schließlich macht der ja Probleme
                      VokeIT GmbH & Co. KG - VokeIT-oss @ github

                      Kommentar


                      • #26
                        Zitat von G.Schuster Beitrag anzeigen
                        ???
                        controller::init() meinst du wohl.

                        Schließt du in der init() das Lockfile wieder?
                        Das wäre sowieso der interessantere Code gewesen, schließlich macht der ja Probleme
                        Oh... sorry, natürlich meine ich controller::init()

                        Hier der Code von controller::init();
                        PHP-Code:
                            public static function _init() {
                                
                        $path pathinfo($_SERVER['SCRIPT_FILENAME'], PATHINFO_DIRNAME);
                                
                        chdir($path); //zum Pfad schalten
                                // Lock auf das Lockfile legen - wenn in itialisierung schon erfolgte, ist die datei gelockt
                                
                        $lockFileHandle = @fopen($path "\\" __CLASS__ ".lock""wb+");
                                if(
                        flock($lockFileHandleLOCK_EX LOCK_NB)) {
                                    
                        //Init soll vollständig ausgeführt werden weil Datei nicht gelockt war
                                    
                        parent::init(classHardware_ini::getIp(), self::$PORTclassHardware_ini::getTimeout());
                                    
                        //im Ruhezustand DO6 auf High setzen !!!!
                                    // nur im INIT ausführen !!!!
                                    
                        parent::setDigitalOut(self::$ENABLE_4555self::$DEFAULT_4555);
                                    if(
                        classHardware_ini::getUseLcd()) {
                                        
                        parent::initLcd();
                                    }
                                }
                                
                        //Klassenvariablen belegen
                                
                        if(classHardware_ini::getUseLcd()) {
                                    
                        self::$lcd_lines classHardware_ini::getLcdLines();
                                    
                        self::$lcdText array_fill(0self::$lcd_lines'');
                                    
                        self::$lcd_line_length classHardware_ini::getLcdLineLength();
                                }
                            } 
                        Wie man sieht, wird das Lockfile im init() nicht geschlossen.

                        Trotzdem ist es beim Aufruf des nächsten Scripts, das die controller Klasse includiert nicht mehr gelockt.

                        Die drei kritischen Zeilen im init() sind

                        PHP-Code:
                        parent::init(classHardware_ini::getIp(), self::$PORTclassHardware_ini::getTimeout());
                        parent::setDigitalOut(self::$ENABLE_4555self::$DEFAULT_4555);
                        parent::initLcd(); 
                        Wenn sie erneut aufgerufen werden, wird die Hardware wieder auf ihren Urzustand zurückgeseztzt und alles kommt durcheinander.

                        Gruß
                        Jörg
                        www.photonensammler.de

                        Kommentar


                        • #27
                          Ich glaube, jetzt habe ich den Fehler beim Lesen meines eigenen Beitrags selbst gefunden .

                          Ich muss wohl eine Klassenvariable anlegen damit es self::$lockFileHandle heißt.

                          Gruß
                          Jörg
                          www.photonensammler.de

                          Kommentar


                          • #28
                            Bei einem bereits gesetzten Lock sollte AFAIK bereits dein fopen() fehlschlagen.
                            Da ich es wie gesagt nur in CronScripten einsetze, d.h. die direkt beendet werden, passt mein Code nicht ganz, sieht deinem aber sehr ähnlich:
                            PHP-Code:
                            $lockFile dirname(__FILE__).'/my.lock';
                            if(
                            FALSE !== ($lockFH = @fopen($lockFile'w'))) {
                                  if(
                            TRUE !== @flock($lockFHLOCK_EX LOCK_NB)) {
                                        exit;
                                  }
                            }
                            else {
                                  exit;
                            }

                            // Code...

                            @fclose($lockFH);
                            @
                            unlink($lockFile); 
                            VokeIT GmbH & Co. KG - VokeIT-oss @ github

                            Kommentar


                            • #29
                              Zitat von G.Schuster Beitrag anzeigen
                              Bei einem bereits gesetzten Lock sollte AFAIK bereits dein fopen() fehlschlagen.
                              Jetzt funktioniert es so, wie es eigentlich soll.

                              fopen() schlägt aber auch bei gelockter Datei nicht fehl.
                              Womöglich liegt das daran, dass ich unter Windows arbeite?

                              Danke für Eure Hilfe!

                              Gruß
                              Jörg
                              www.photonensammler.de

                              Kommentar


                              • #30
                                Zitat von photonensammler Beitrag anzeigen
                                fopen() schlägt aber auch bei gelockter Datei nicht fehl.
                                Womöglich liegt das daran, dass ich unter Windows arbeite?
                                Kommt auf den Sharingmodus an, in dem die Datei geöffnet wurde.
                                Öffne die Datei exklusiv im Schreib-/Lesemodus, dann sollten alle weiteren Öffnungsversuche scheitern.
                                Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                                Kommentar

                                Lädt...
                                X