Ankündigung

Einklappen
Keine Ankündigung bisher.

Vorkompilieren von WG-Plugins, möglicher Fix für bisherige Memleaks

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

    [WireGate-Plugin] Vorkompilieren von WG-Plugins, möglicher Fix für bisherige Memleaks

    Hallo zusammen,

    Kurzfassung: hier ist ein EXPERIMENTELLES neues Feature für das Wiregate (oder Communitygate, whatever): Vorkompilieren von Plugins mit dem Zweck

    * der schnelleren Ausführung
    * und weniger Memleaks.

    Es handelt sich um einen Patch für den Wiregate-Daemon. Die Geschichts sollte vollständig abwärtskompatibel zu heutigen Plugins sein.

    Langfassung:

    Hintergrund der Entwicklung sind die leidigen Memleaks bei Plugins, die auf die Dauer immer wieder zum Neustart führen, außerdem die Tatsache, dass gewisse "zeitkritische" Plugins wie Logikprozessor, Russound_RIO usw. manchmal recht träge reagieren.

    Die Ursache für beides vermutete ich in den zahlreichen "eval"-Aufrufen, die im wiregated-Daemon geschehen:

    1. Jedes Plugin wird bei jedem Aufruf per eval neu geparset und dann ausgeführt.

    2. Durch die Programmierweise der meisten - auch meiner - Plugins, geschieht sogar noch ein verschachteltes zweites "eval" innerhalb des Plugins für die Konfigurationsdatei.

    Dem wollte ich abhelfen und habe überlegt, wie man das ständige Parsen reduzieren kann. Natürlich muss die Lösung abwärtskompatibel sein, damit heutige Plugins noch laufen. Mein Vorschlag: ausgewählte Plugins, die häufig laufen, werden vorkompiliert und in diesem Zustand gespeichert.

    Konkret funktioniert das so: falls ein Plugin irgendwo das Schluesselwort COMPILE_PLUGIN enthält - etwa in einer Kommentarzeile - dann versucht der wiregated dieses Plugin in eine namenlose Subroutine (closure) zu verwandeln. Gelingt dieses nicht fehlerfrei, oder ist das Schluesselwort COMPILE_PLUGIN nicht vorhanden, so wird das Plugin wie bisher per "eval" interpretiert, ohne es zu kompilieren. Gelingt aber der Kompiliervorgang, wird der Plugincode vorkompiliert gecachet und muss ab sofort nur noch aufgerufen werden.

    Die praktische Umsetzung funktioniert so, dass um das Plugin herum der Text "sub { .... }" gepackt wird, das Ergebnis durch eval geschickt wird und dessen Ergebnis wiederum in einem Hash %plugin_code für die spätere Ausführung gespeichert wird.

    Kein Licht ohne Schatten: wenn man Plugins "kompilierbar" schreiben will, muss man eine Regel beachten, die damit zusammenhängt, dass das Plugin am Ende eine Subroutine wird und Perl benannte Subroutinen innerhalb von anderen Subroutinen eigentlich nicht kennt.

    Die einzige konkrete Auswirkung dieses Umstandes, die mir einfällt: Subroutinen innerhalb von kompilierten Plugins können NICHT mehr auf Variablen im Haupttext des Plugins zugreifen. (Sie können aber wie bisher auf ihre eigenen lokalen ("my") Variablen zugreifen und auch auf die Variablen des Daemons, zB %msg und $fh, oder auch %plugin_subscribe).

    Beispiel

    Code:
    my $a=1;
    my $b=3;
    sub MySub; # Deklaration
    
    plugin_log($plugname, "Test=".MySub()); # Aufruf
    
    sub MySub { return $a+$b; }  # geht NICHT, Compilerfehler
    (sowas ist übrigens sowieso schlechter Programmierstil, aber über Stil zu diskutieren ist un-PERL-ig).

    Workaround: Um das zu umgehen, muss man die Variablen explizit übergeben:

    Code:
    my $a=1;
    my $b=3;
    sub MySub; # Deklaration
    
    plugin_log($plugname, "Test=".MySub($a,$b)); # Aufruf mit Übergabe
    
    sub MySub { my ($a,$b)=@_; return $a+$b; }  # korrekt
    Ein anderer Workaround wäre, die Sub ebenfalls als Closure zu definieren, denn die vorgenannte Komplikation besteht nur bei benannten Subroutinen:

    Code:
    my $a=1;
    my $b=3;
    local *MySub = sub { return $a+$b}; # Definition jetzt VOR dem ersten Aufruf!
    
    plugin_log($plugname, "Test=".MySub()); # geht
    (wer mehr wissen will -> man perlref und nach Function Templates suchen).

    Zwei weitere, sehr einfache und vom Vorgenannten getrennte Ideen zur Wiregated-Verbesserung habe ich auch umgesetzt:

    1. Um Plugin-Konfigurationen zwischenzuspeichern, sollte neben %plugin_info (das per tie an eine Datenbank angebunden ist, damit persistent, aber langsam und auf skalare Daten beschränkt) noch ein %plugin_cache existieren. Daten, die hier abgelegt werden, sind nach einem Neustart des wiregated weg, dafür sind sie zwischendurch schnell verfügbar und bei geschickter Plugin-Programmierung kann man so auch auf die eval-Aufrufe für die Konfigurationsdatei verzichten (bis auf einmal in der allerersten Initialisierung des Plugins). Ich schlage vor, ein solches %plugin_cache innerhalb Plugins so zu benutzen:

    Code:
    $plugin_cache{$plugname}{simpel}=4; # ein simples Beispiel
    $plugin_cache{$plugname}{komplex}=\%my_big_hash; # hier wird ein ganzes Hash zwischengespeichert
    Wenn man das bewusst einsetzt, kann man auch das Einlesen von Konfigurationen stark reduzieren. Ich habe natürlich auch den Logikprozessor kompilierbar gemacht (die conf-Dateien bleiben dabei völlig unverändert) und speichere die Logiken nun in %plugin_cache ab -> deutlicher Geschwindigkeitszuwachs, und auch die Memleaks sehe ich seitdem subjektiv deutlich reduziert. Den kompilierbaren Logikprozessor stelle ich aber erstmal nicht ins SVN sondern poste ihn hier, weil er von %plugin_cache abhängt und ich erst warten will, ob der Patch angenommen wird.

    2. knx_write sieht aktuell die Möglichkeit vor, write- und response-Requests abzusetzen. (Für response muss man nur den vierten Parameter beim Aufruf auf 1 setzen). Man braucht aber auch die Möglichkeit, ein non-blocking-Read-telegramm abzusetzen, also die Leseanfrage zu schicken, ohne dass man auf die Antwort überhaupt wartet. Anwendungsbeispiel: man möchte regelmäßig einen Wert von einem Aktor abfragen, der das zyklische Senden dieses Wertes nicht unterstützt. Dann helfen solche non-blocking Read-Requests.

    #2
    ...und hier ist der Patch für wiregated.pl.

    Achtung: EXPERIMENTAL. Wer Patches nicht selbst einspielen bzw. im Fehlerfall zurückrollen kann, sollte dieses Feature jetzt noch nicht ausprobieren!

    Code:
    83a84,85
    > my %msg;                                                                                                                                        
    > my $fh;                                                                                                                                         
    394c396,398
    <   my $apci = ($response) ? 0x40 : 0x80; # 0x40=response, 0x80=write                                                                             
    ---
    >   my $apci = 0x80; # 0x40=response, 0x80=write, 0x00=non-blocking read                                                                          
    >   $apci = ($response==2 ? 0 : ($response==1 ? 0x40 : ($response==0 ? 0x80 : $response))) if defined $response;                                  
    >                                                                                                                                                 
    921a926
    >                                                                                                                                                 
    945d949
    <                                                                                                                                                 
    962a967,968
    > my %plugin_cache=(); # non-persistent but faster memory for plugins                                                                             
    > my %plugin_code=(); # here, the plugins are stored as closures (unnamed subs)                                                                   
    1033c1039
    <          my %msg = decode_vbusmonitor($$eibbuf2);                                                                                               
    ---
    >          %msg = decode_vbusmonitor($$eibbuf2);                                                                                                  
    1099c1105
    <             check_generic_plugins($k,\%msg);                                                                                                    
    ---
    >             check_generic_plugins($k);                                                                                                          
    1118c1124
    <       &check_generic_plugins();                                                                                                                 
    ---
    >       check_generic_plugins();                                                                                                                  
    1121c1127
    <       check_global_rrd_update;                                                                                                                  
    ---
    >       check_global_rrd_update();                                                                                                                
    1136c1142,1143
    <         foreach my $fh (@sock_ready) {                                                                                                          
    ---
    >        for my $fhi (@sock_ready) {                                                                                                              
    >           $fh=$fhi; # important! different lexical scoping of $fh and $fhi!                                                                     
    1140c1147,1148
    <                 &check_generic_plugins($plugin_socket_subscribe{$fh},undef,$fh);                                                                
    ---
    >               %msg=();                                                                                                                          
    >                 check_generic_plugins($plugin_socket_subscribe{$fh});                                                                           
    1165,1167c1173
    <     my $runname = $_[0];                                                                                                                        
    <     my %msg;                                                                                                                                    
    <     my $fh;                                                                                                                                     
    ---
    >     my $runname = shift;                                                                                                                        
    1169,1172d1174
    <     if (defined $_[1]) { %msg = %{$_[1]}; } else { %msg = (); }                                                                                 
    <     if (defined $_[2]) { $fh = $_[2]; } else { $fh = undef; }                                                                                   
    <     #%msg =() unless defined %msg;                                                                                                              
    <     #my %msg ;   # dummy definition - empty so plugins can determine if called by subscribed ga or cycle                                        
    1174,1178c1176,1181
    <     my @plugins = </etc/wiregate/plugin/generic/*>;                                                                                             
    <     foreach (@plugins) {                                                                                                                        
    <       next if ($_ =~ /\~$/ or -d $_); # ignore backup-files and subdirectories                                                                  
    <       my $plugname = basename($_);                                                                                                              
    <       $plugin_info{$plugname.'_lastsaved'} = ((stat($_))[9]);                                                                                   
    ---
    >                                                                                                                                                 
    >     my @plugins = grep !/[\~\#]$/ && !-d $_, </etc/wiregate/plugin/generic/*>; # ignore backup-files and subdirectories                         
    >     for my $plugfile (@plugins)                                                                                                                 
    >     {                                                                                                                                           
    >       my $plugname = basename($plugfile);                                                                                                       
    >       $plugin_info{$plugname.'_lastsaved'} = ((stat($plugfile))[9]);                                                                            
    1180,1183c1183,1218
    <       if ((time() > $plugin_info{$plugname.'_last'} + $plugin_info{$plugname.'_cycle'} and $plugin_info{$plugname.'_cycle'}) # check cyclic plu\
    gin                                                                                                                                               
    <           or $plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'}    # check changed plugin                                   
    <           or $runname eq $plugname # direct call                                                                                                
    <           or !$plugin_initflag) {                                                                                                               
    ---
    >                                                                                                                                                 
    >       # Parse, compile and cache plugins upon initialization or modification                                                                    
    >       if( $plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'} || !$plugin_initflag)                                          
    >       {                                                                                                                                         
    >           # reset error counters                                                                                                                
    >           $plugin_info{$plugname.'_timeout_err'}=0;                                                                                             
    >           $plugin_info{$plugname.'_meminc'}=0;                                                                                                  
    >           $plugin_info{$plugname.'_memstart'}=0;                                                                                                
    >           $plugin_info{$plugname.'_ticks'}=0;                                                                                                   
    >                                                                                                                                                 
    >           # parse and cache the code                                                                                                            
    >           open FILE, "<$plugfile";                                                                                                              
    >           my $source=join '', <FILE>;                                                                                                           
    >           close FILE;                                                                                                                           
    >                                                                                                                                                 
    >           if($source=~/COMPILE_PLUGIN/)                                                                                                         
    >           {                                                                                                                                     
    >               LOGGER('DEBUG',"Compiling PLUGIN $plugname");                                                                                     
    >               plugin_log($plugname, "COMPILING");                                                                                               
    >                                                                                                                                                 
    >               eval "\$plugin_code{\$plugname}=sub {\n $source \n};\n";                                                                          
    >                                                                                                                                                 
    >               if ($@ || !$plugin_code{$plugname})                                                                                               
    >               {                                                                                                                                 
    >                   LOGGER('DEBUG',"Compile-time ERROR in $plugname $@");                                                                         
    >                   $plugin_info{$plugname.'_result'} = 'Compile-time:'.$@;                                                                       
    >                   delete $plugin_code{$plugname};                                                                                               
    >               }                                                                                                                                 
    >           }                                                                                                                                     
    >       }                                                                                                                                         
    >                                                                                                                                                 
    >       # Execute plugins that are due, or on a direct call from a subscribed GA/socket (via plugin_subscribe)                                    
    >       if( $plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'}                                                                
    >           || time() > $plugin_info{$plugname.'_last'} + $plugin_info{$plugname.'_cycle'} && $plugin_info{$plugname.'_cycle'}                    
    >           || $runname eq $plugname || !$plugin_initflag)                                                                                        
    >       {                                                                                                                                         
    1184a1220
    > #       plugin_log($plugname, "RUNNING");                                                                                                       
    1186,1195d1221
    <           open(FILE, $_);                                                                                                                       
    <           my @lines = <FILE>;                                                                                                                   
    <           close($_);                                                                                                                            
    <           # if modified and once on init, reset error-counter, mem-stats                                                                        
    <           if (($plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'}) or !$plugin_initflag) {                                  
    <             $plugin_info{$plugname.'_timeout_err'}=0;                                                                                           
    <             $plugin_info{$plugname.'_meminc'}=0;                                                                                                
    <             $plugin_info{$plugname.'_memstart'}=0;                                                                                              
    <             $plugin_info{$plugname.'_ticks'}=0;                                                                                                 
    <           }                                                                                                                                     
    1204c1230,1255
    <             $plugin_info{$plugname.'_result'} = eval("@lines");                                                                                 
    ---
    >                                                                                                                                                 
    >               if($plugin_code{$plugname})                                                                                                       
    >               {                                                                                                                                 
    >                   eval { $plugin_info{$plugname.'_result'} = $plugin_code{$plugname}->(); };                                                    
    >                                                                                                                                                 
    >                   if ($@)                                                                                                                       
    >                   {                                                                                                                             
    >                       LOGGER('DEBUG',"ERROR in $plugname $@");                                                                                  
    >                       $plugin_info{$plugname.'_result'} = 'Run-time: '.$@;                                                                      
    >                   }                                                                                                                             
    >               }                                                                                                                                 
    >               else                                                                                                                              
    >               {                                                                                                                                 
    >                   open FILE, "<$plugfile";                                                                                                      
    >                   my $source=join '', <FILE>;                                                                                                   
    >                   close FILE;                                                                                                                   
    >                                                                                                                                                 
    >                   $plugin_info{$plugname.'_result'} = eval $source;                                                                             
    >                                                                                                                                                 
    >                   if ($@)                                                                                                                       
    >                   {                                                                                                                             
    >                       LOGGER('DEBUG',"ERROR in $plugname $@");                                                                                  
    >                       $plugin_info{$plugname.'_result'} = 'Run-time: '.$@;                                                                      
    >                   }                                                                                                                             
    >               }                                                                                                                                 
    >               else                                                                                                                              
    >               {                                                                                                                                 
    >                   open FILE, "<$plugfile";                                                                                                      
    >                   my $source=join '', <FILE>;                                                                                                   
    >                   close FILE;                                                                                                                   
    >                                                                                                                                                 
    >                   $plugin_info{$plugname.'_result'} = eval $source;                                                                             
    >                                                                                                                                                 
    >                   if ($@)                                                                                                                       
    >                   {                                                                                                                             
    >                       LOGGER('DEBUG',"ERROR in $plugname $@");                                                                                  
    >                       $plugin_info{$plugname.'_result'} = $@;                                                                                   
    >                   }                                                                                                                             
    >               }                                                                                                                                 
    >

    Kommentar


      #3
      ... und wer den Logikprozessor in einer kompilierbaren Fassung ausprobieren will, für den ist er hier angehängt.
      Have fun,
      Fry
      Angehängte Dateien

      Kommentar


        #4
        Hallo Fry,

        folgen kann ich dem Code nicht mehr - so viel vorweg.

        Was ich festgestellt habe ist, dass die Memleaks auch plattformabhängig sind.
        Mit dem knxd auf einem Pi und einem WireGate liegen im Speicherverbrauch Welten.

        Mein eBus-Plugin läuft derzeit nur auf dem knxd da ich dort sowohl den angebotenen RRD-COUNTER-Patch als auch den neuen Plugin-Subscribe-Patch angewendet habe.

        Das identische Plugin, der identische Daemon verhalten sich total unterschiedlich. Auf dem Pi verbrauche ich 0.01 MB/Woche. Das Plugin wird alle 10 Sekunde aufgerufen, macht ein eval durch die config, parst 30 Zeilen CSV und stellt eine Telnet-Verbindung her. Auf dem WireGate (nicht meines) wurde mir von 20.00 MB/Tag für den knxd berichtet. Das wundert dann schon.

        Eigentlich müsste man mal den wiregated.pl auf nen Pi ziehen, den ganzen Webmin-Kram könnte man ja erstmal weglassen, aber so viel Langeweile hab ich momentan nicht.

        Grüße
        Umgezogen? Ja! ... Fertig? Nein!
        Baustelle 2.0 !

        Kommentar


          #5
          Die Memleaks habe ich auch nie verstanden, allerdings führen wiederholte evals gerne zu irgendwelchen Redefinitionen, und da kann es dann schon Memleaks geben. (Gibt sogar ein paar dokumentierte Beispiele irgendwo).

          Ehrlich: meine Hauptmotivation war die Beschleunigung des Logikprozessors. Und natürlich habe ich den knxd genauso modifiziert (ist straightforward).

          Und der Beschleunigungsfaktor des Logikprozessors ist gefühlt Faktor 3. Hat sich für mich also gelohnt.

          VG, Fry

          Kommentar


            #6
            Darf ich dich bitten das im SVN auch zu machen?

            Wenn Du die folgenden Patches auch im wiregated.pl anwendest dann kannst Du das eBus-Plugin auch direkt dort nutzen.

            https://knx-user-forum.de/forum/supp...wiregate/25541

            https://knx-user-forum.de/forum/supp...wiregate/27297

            Grüße
            Umgezogen? Ja! ... Fertig? Nein!
            Baustelle 2.0 !

            Kommentar


              #7
              Deine Idee mit subscribe-read und -write finde ich gut (wäre nett auch noch ein subscribe-response zu machen, dann kann man ein Read-Telegramm absetzen und das Plugin beenden, ein erneuter Aufruf kommt dann ggf später mit der Response). Die RRD-Geschichte verstehe ich noch nicht.

              Lass uns erst mal abwarten, ob Makki unsere Patches in den Hauptzweig übernimmt. Ich gehe davon aus, dass er hier mitliest.

              VG, Fry

              Kommentar


                #8
                Es wäre übrigens straightforward, den kompletten Logikprozessor in den wiregated.pl einzubauen. Lohnt sich aber nur, wenn dafür auch entsprechende Performancevorteile kommen. Oder der Webmin so angepasst wird, dass man dann einzelne Logiken bearbeiten kann.

                VG, Fry

                Kommentar


                  #9
                  Ob Makki das derzeit mitliesst weiß ich nicht, weil er gerade in seinem verdienten Sabbatical ist.

                  Aber unsere Firma besteht aus 10 Mitarbeiter und nicht nur aus Makki und wir anderen lesen sehr wohl mit und werden uns die sehr interessanten Vorschläge auch näher ansehen.

                  Das Vorkompilieren hatten wir auch schon letztes Jahr intern besprochen, jedoch wegen Sorgen mangelnder Kompatibilität zu bisherigen Plugins wieder verworfen.

                  Wenn ihr das für euch testet und berichtet erleichtert es uns die Sache sehr.

                  Auch die Aufnahme des Logikprozessors ist eine Diskussion wert.

                  lg

                  Stefa

                  Kommentar


                    #10
                    Kleine Plugins ohne eigene "subs" funktionieren ohne Änderung. Für die anderen sind die Änderungen ziemlich einfach. Ändern muss man auch nur, wenn man das Vorkompilieren nutzen will. Alle Plugins, die jetzt im SVN stehen, enthalten NICHT das Schlüsselwort COMPILE_PLUGIN und werden deshalb auch nicht kompiliert und laufen wie bisher.

                    Eine ordentliche Testphase steht natürlich noch aus, bevor man das in euer Produkt übernimmt.

                    VG, Fry

                    Kommentar


                      #11
                      Kurze Zwischenmeldung: ich musste noch hier und da was anpassen, für die Kompilierbarkeit gewisser Plugins und für die Nutzung des neuen %plugin_cache, und natürlich ein paar Bugs entfernen, aber jetzt läuft der Logikprozessor bei mir mit ~300 Logiken sehr zuverlässig ohne (merklichen) Memleak und um einen Faktor >40 schneller.

                      Als Konsequenz konnte ich auch mein Setup wieder vereinfachen.

                      Zwischendurch hatte ich einen dedizierten Raspberry Pi mit Jumis knxd versehen. Der machte nur ausgewählte, zeitkritische Logiken, die im Wiregate wegen dessen eigener Mehrfachbelastung nicht schnell genug liefen. Das Wiregate machte den Rest.

                      So richtig zufrieden war ich mit diesem Setup aber nicht, weil ich dem RPi nicht traue bezüglich Langzeitstabilität (SD-Karte als Festplatte). Außerdem war das Setup damit natürlich komplexer. Dann habe ich mit linknx angesehen - knxweb ist zwar ganz nett, aber fügt schon wieder eine neue Komponente hinzu. Und irgendwie mag ich kein Geklicke, und XML händisch eingeben ist ein Krampf.

                      Jetzt habe ich alles wieder ins Wiregate zurückverlegt. Heizungsregler, Logikprozessor, Schlüsselbrett, Alarmanlage, Anwesenheitssimulation, Szenencontroller, Ansagen, ChrisMs Russound_RIO. Alles kompilierbar gemacht und kompiliert und damit beschleunigt. Und es funktioniert absolut zu meiner Zufriedenheit (bisheriger Testverlauf).

                      Der RPi hat natürlich nicht ausgedient, und auch der knxd nicht. Für die finde ich schon wieder neue Spielereien...

                      Jetzt warte ich aber mal auf Makkis Rückkehr für die weitere Stoßrichtung. Am liebsten wäre mir, wir könnten diese Dinge in den Hauptzweig übernehmen. Am Rande: mir wäre auch ein Merger von wiregated und knxd sehr willkommen (zB ein wiregated mit (per Option) abschaltbarem 1-wire-Teil).

                      VG, Fry

                      Kommentar


                        #12
                        Hallo zusammen,

                        Weitere Zwischeninfo: mit dem modifizierten wiregated.pl und den (minimal) angepassten Plugins läuft das Wiregate nun seit 7 Tagen ohne Booten durch (und der Grund fürs Booten vor 7 Tagen hing mit mpd und pulseaudio zusammen, die leider immer noch nicht stotterfreie Ansagen liefern).

                        Keine Logik und kein Plugin brauchen nennenswert Laufzeit (Wert im Log maximal "0.3s"). (Ausnahmen sind Blockaden durch das Warten auf den Bus, die habe ich aber auch gefunden und eliminiert).

                        Fazit: die Anpassung hat deutlich zur Stabilität und Geschwindigkeit beigetragen. Für mich gibt es kein Zurück mehr.

                        Jemand Interesse, das bei sich auszutesten?

                        VG, Fry

                        PS. Was übrigens auch noch erheblich helfen würde, gewisse Selbstblockaden des Wiregate zu beheben: knx_read so modifizieren, dass

                        (i) dass auf dem Bus das Lesetelegramm abgesetzt und nur wenige ms (einstellbar) auf die Antwort gewartet wird -> falls keine Antwort, Rückgabe undef

                        (ii) dass auf Wunsch die Abfragen der 1wire-Werte abgefangen werden und in solchen Fällen nach dem Absetzen des Lesetelegramms gar nicht auf den Bus gewartet wird, sondern stattdessen der 1wire-Sensor abgefragt wird und dessen Antwort zurückgegeben (und auf den Bus geschrieben) wird

                        (bereits vorgeschlagen habe ich ja (iii) die Möglichkeit, mit knx_write Lesetelegramme abzusetzen, ohne überhaupt auf die Antwort zu warten).

                        Jemand Interesse, das zu implementieren?

                        Kommentar


                          #13
                          Zitat von Fry Beitrag anzeigen
                          Weitere Zwischeninfo: .....Keine Logik und kein Plugin brauchen nennenswert Laufzeit (Wert im Log maximal "0.3s").
                          Finde ich absolute Klasse !


                          Zitat von Fry Beitrag anzeigen
                          Jemand Interesse, das bei sich auszutesten?
                          Zitat von Fry Beitrag anzeigen
                          Jemand Interesse, das zu implementieren?

                          Falls jemand entweder einen sehr umfangreichen Anwendungsfall hat (also eine sehr große Menge an Logiken auf Basis Plugins und den Umstieg testen will) oder die Vorschläge von Fry implementieren möchte, aber das lieber auf einem separaten Wiregate 1 Multifunktionsgateway ausführen will, der kann durchaus eines von uns gesponsert bekommen. Gilt auch für Dich Fry.

                          ==> Bitte entsprechend begründeten "Antrag" an support @ wiregate dot de


                          mfg

                          Stefan

                          Kommentar


                            #14
                            Hoi

                            Wär' das nicht was für den Diego Fechter65 ?
                            Grüsse Bodo
                            Fragen gehören ins Forum, und nicht in mein Postfach;
                            EibPC-Fan; Wiregate-Fan; Timberwolf-Fan mit 30x 1-Wire Sensoren;

                            Kommentar


                              #15
                              Hallo zusammen,

                              durch Makkis sicher wohlverdienten Langzeiturlaub (ich hoffe, er postet dann mal ein paar Fotos :-) verzögert sich offenbar die Entscheidung über den oben geposteten wiregated.pl-Patch.

                              Bei mir läuft das Wiregate nun schon seit Wochen stabil (in der Tat stabiler als vorher) mit dem neuen Ansatz der "vorkompilierten" Plugins und einiger weiterer (kleinerer) Verbesserungen. Ausdrücklich: abwärtskompatibel! Alte Plugins werden weiterhin und wie bisher ausgeführt, erst ein Kommentar "# COMPILE_PLUGIN" im Plugin-Code aktiviert das Kompilieren für dieses Plugin.

                              Wer es mal ausprobieren möchte, dem hänge ich hier meine aktuelle (seit Wochen unveränderte) Fassung des Daemons wiregated.pl und des Plugins Logikprozessor.pl an. Die Config-Datei des Logikprozessors bleibt unverändert (nur läuft er jetzt viel schneller).

                              Ausdrücklich wie immer OHNE GEWÄHR. (das ist zwar selbstverständlich bei freier Software, ich schreibe es aber nochmal dazu).

                              Die angehängte Datei ist ein "tarball", keine ZIP-Datei (Dateiendung geändert, sonst kriege ich sie hier nicht gepostet). Drin enthalten enthält zwei Dateien: /usr/sbin/wiregated.pl und /etc/wiregate/plugin/generic/Logikprozessor.pl.

                              Zu Ausprobieren das Attachment ins Wurzelverzeichnis des Wiregate kopieren, in "wglp.tgz" umbenennen und mit "tar xvzf wglp.tgz" entpacken.

                              Mit dem Einstellen ins SVN will ich weiter warten, bis Makki sich das mal angesehen hat.

                              Have fun,
                              Fry
                              Angehängte Dateien

                              Kommentar

                              Lädt...
                              X