PRESENCE Fhem Absturz

Begonnen von ChrisW, 03 Februar 2013, 15:54:42

Vorheriges Thema - Nächstes Thema

ChrisW

das war der letzet FHEM Log eintrag bevor er abgestürzt ist :
2013.02.05 08:42:39 1: ERROR: Select error -1 (10038), error count= 0

Hier meine blocking.pm
##############################################
# $Id: $
package main;

=pod
### Usage:
sub TestBlocking() { BlockingCall("DoSleep", 5, "SleepDone", 8); }
sub DoSleep($)     { sleep(shift); return "I'm done"; }
sub SleepDone($)   { Log 1, "SleepDone: " . shift; }
=cut


use strict;
use warnings;
use IO::Socket::INET;
use threads;

sub BlockingCall($$@);

sub
BlockingCall($$@)
{
  my ($blockingFn, $arg, $finishFn, $timeout) = @_;

  my $pid = fork;
  if(!defined($pid)) {
    Log 1, "Cannot fork: $!";
    return undef;
  }

  if($pid) {
    InternalTimer(gettimeofday()+$timeout, "BlockingKill", $pid, 0)
      if($timeout);
    return $pid;
  }

  # Child here
  no strict "refs";
  my $ret = &{$blockingFn}($arg);
  use strict "refs";

  exit(0) if(!$finishFn);

  # Look for the telnetport
  my $tp;
  foreach my $d (sort keys %defs) {
    my $h = $defs{$d};
    next if(!$h->{TYPE} || $h->{TYPE} ne "telnet" || $h->{TEMPORARY});
    next if($attr{$d}{SSL} || $attr{$d}{password});
    next if($h->{DEF} =~ m/IPV6/);
    $tp = $d;
    last;
  }

  if(!$tp) {
    Log 1, "CallBlockingFn: No telnet port found for sending the data back.";
    threads->exit();
  }

  # Write the data back, calling the function
  my $addr = "localhost:$defs{$tp}{PORT}";
  my $client = IO::Socket::INET->new(PeerAddr => $addr);
  Log 1, "CallBlockingFn: Can't connect to $addr\n" if(!$client);
  $ret =~ s/'/\\'/g;
  syswrite($client, "{$finishFn('$ret')}\n");
  threads->exit();
}

sub
BlockingKill($)
{
  my $pid = shift;
  Log 1, "Terminated $pid" if($pid && kill(9, $pid));
}


1;
Raspberry PI3 mit allem möglichen.

ChrisW

Und mir ist noch etwas aufgefallen wenn ich das in Fhem eintrage:
define HandyChris PRESENCE lan-ping 192.168.2.50 30

Kommt eine 00_CUL error ( hab ich leider nicht mehr die Meldung )
Ich kann keine Funksteckdosen mehr schalten ..
2013.02.05 09:56:49 2: IT IODev device didn't answer is command correctly:   raw => No answer

Ausgebaut fhem restart geht wieder..
Raspberry PI3 mit allem möglichen.

ChrisD

Hallo,

Ich habe eine ganze Reihe an Tests mit diversen Blocking.pm Versionen (original, Patch von Markus, SVN mit Patch, eigene Varianten) sowie ActivePerl und Strawberry Perl gemacht. Leider habe ich bis jetzt keine einzige Kombination gefunden welche längerfristig funktioniert. Insbesondere wenn mehrere PRESENCE-Bausteine gleichzeitig verwendet werden kommt es relativ schnell zum Absturz.

Ich bin auch nicht sicher ob die Änderung mit thread->exit() verhindert dass die Schnittstellen geschlossen werden. Ich benutze eine FHZ1000PC und einen CUL. Im PortMonitor von Sysinternals kann ich sehen dass die Schnittstelle des CULs kurz nach dem Aufruf von thread->exit() geschlossen wird, die der FHZ1000PC dagegen nicht. Es kommt aber keine Meldung (Error in PurgeComm ...), es werden aber keine Daten mehr über den CUL empfangen.

Ich werde als nächstes versuchen Perl unter Cygwin zu verwenden, hier wird fork anscheinend nicht emuliert.

Grüße,

ChrisD





Markus Bloch

Hi Chris,

nach den heutigen Änderungen in PRESENCE und den letzten Änderungen habe ich bisher noch keinen Absturz von FHEM unter Windows gehabt.

Probier es morgen nach einem update mal bitte aus.

Viele Grüße

Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

ChrisW

hi, vor 5 Minuten Update gemacht nur die 1. Zeile wie es oben steht eingebaut. nach 1-2 Minuten folgendes in der Konsole:
Select error -1 (10038)
Error in PurgeComm at fhem.pl line 0.
Das Handle ist ung³ltig.
Error in GetCommTimeouts at fhem.pl line 0.
Error Closing handle 132 for \\.\com3
Das Handle ist ung³ltig.
Error closing Read Event handle 176 for \\.\com3
Das Handle ist ung³ltig.
Error closing Write Event handle 180 for \\.\com3
Das Handle ist ung³ltig.


und das im fhem Log:
2013.02.08 09:24:55 1: ERROR: Select error -1 (10038), error count= 0
Raspberry PI3 mit allem möglichen.

ChrisD

Hallo,

Ich habe das Update auf die neue Version gemacht. Leider ist das Problem damit nicht behoben, ich habe ähnliche Meldungen wie ChrisW mit ActivePerl und Strawberry.

Mit Cygwin läuft das PRESENCE-Modul mit dem CUL jetzt seit 30 Stunden. Mit dem neuen PRESENCE-Modul funktioniert es unter Cygwin aber nicht mehr da die Abfrage if($^O =~ m/Win/) ... auf Cygwin nicht zutrifft und somit versucht wird den Ping des Betriebssystems zu benutzen. Dabei passen aber weder die Aufrufparameter (-c) noch das Format der Rückgabewerte. Ich habe deshalb die Abfrage in if(($^O =~ m/Win/) || ($^O =~ m/cygwin/)) umgeändert.

Positiv bei Cygwin:
- PRESENCE funktioniert mit CUL, es wird bei jedem fork ein eigener Perl-Prozess gestartet
- shutdown restart funktioniert (ohne Modifikation an fhem.pl)

Negativ:
- aufwendigere Installation
- nach einem Neustart des Rechners kommt die Kommunikation zum CUL nicht zustande (Can't open /dev/ttyS12: Invalid argument), ein Mal fhem über Strawberry starten und CUL initialisieren lassen reicht aber aus. Da ich den Server quasi nie neu starte ist dies für mich kein Problem
- beim Starten von fhem kommt es manchmal zu einer längerer Wartezeit beim Öffnen des CULs, die Wartezeit hängt dabei von der Anzahl der PRESENCE-Bausteine ab (3 Minuten bei 4 Bausteinen, 5 Minuten bei 8)
- die geforkten Perl-Instanzen stürzen mit einer Exception ab, dies scheint aber keinerlei Auswirkung auf die Funktion zu haben, unschön ist nur dass das Shell-Fenster voller Stack-Traces ist

Beim PRESENCE-Modul sind mir auch noch ein paar merkwürdige Effekte aufgefallen die ich noch untersuche. Einer davon betrifft das Disable-Attribut. Wenn es auf 1 ist sollte das Modul meiner Meinung nach nichts machen. Es wird aber trotzdem ein Ping beim starten gemacht. In PRESENCE_Define wird nämlich immer (unabhängig vom Zustand von Disable) PRESENCE_StartLocalScan($hash); aufgerufen.

Im Moment werde ich bei Cygwin bleiben, kann aber weiterhin Tests mit den beiden anderen machen.

Grüsse,

ChrisD

Markus Bloch

Hallo Chris,

ich habe deinem Vorschlag entsprechend Cygwin mit aufgenommen und PRESENCE_Define() so angepasst, dass nun das disable-Attribut berücksichtigt wird.

Generell ist cygwin hier die beste Wahl, da es der Unix-Welt am nächsten kommt. Da ich unter Windows kein FHEM mit CUL betreibe, kann ich euch da leider nicht wirklich unterstützen. Ohne ein CUL läuft das Modul ohne Probleme unter Windows.

Ich bin daher über jeden Tipp dankbar um PRESENCE auch unter Windows mit CUL stabil zu bekommen.

Viele Grüße

Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

ChrisD

Hallo,

Ich habe deine Änderung eingespielt. Leider hat der Patch nicht den gewünschten Effekt. In meine Config-Datei habe ich:

define CHK_P1 PRESENCE lan-ping 192.168.0.100 15
attr CHK_P1 disable 1


Ich habe einige Log-Aufrufe in 73_PRESENCE hinzugefügt und festgestellt dass beim Aufruf von PRESENCE_Define Disable noch undefiniert ist. Erst 2s später wird Disable über PRESENCE_Attr gesetzt.

Die 2s Verzögerung kommen übrigens aus der Funktion InternalTimer. Diese blockiert fhem komplett da zum Zeitpunkt des Aufrufes aus PRESENCE_Define $init_done=0 und $waitIfInitNotDone=1 ist. Der Aufruf von InternalTimer aus der _Define-Funktion scheint mir keine gute Idee. Gibt es keine Möglichkeit global:INITIALIZED auszuwerten und erst hierüber die PRESENCE-Funktion zu starten ?

Grüsse,

ChrisD

ChrisW

Heute neuer Test immer noch:
c:\fhem>perl fhem.pl fhem.cfg
Select error -1 (10038)
Error in PurgeComm at fhem.pl line 0.
Das Handle ist ung³ltig.
Error in GetCommTimeouts at fhem.pl line 0.
Error Closing handle 132 for \\.\com3
Das Handle ist ung³ltig.
Error closing Read Event handle 176 for \\.\com3
Das Handle ist ung³ltig.
Error closing Write Event handle 180 for \\.\com3
Das Handle ist ung³ltig.


Es lief aber ca 4 Minuten

FHEMLOG:
2013.02.12 13:51:46 1: ERROR: Select error -1 (10038), error count= 0
Raspberry PI3 mit allem möglichen.

Reinerlein

Hi Markus,

wir hatten ja schon per PN Kontakt zu dem Thema...

Besteht denn in deiner Anwendungsstruktur die Möglichkeit die Thread-Beendigung zu verhindern?

Ich habe meinen Code für Sonos ja auch so umgestellt, dass ich denselben Thread immer wieder verwende, und die notwendigen Informationen und Aufträge in beiden Threads synchronisiere bzw. per Signalling und Queues transportiere.
Eine Baustelle habe ich da aber auch immer noch, mal schauen, was ich damit mache :-)

Vielleicht wäre das auch ein Ansatz bei dir. Allgemein wird das in den Perl-Foren, die sich mit Threading beschäftigen, auch empfohlen, da das Erzeugen eines Threads ja sehr Zeitaufwändig ist. Leider kann man es nur nicht immer so umsetzen (man kann ja z.B. keine Objekte transportieren o.ä.).

Grüße Reinerlein

justme1968

ein vorschlag in eine ähnliche richtung: wie wäre es den das ping über den presenced zu machen? der könnte einfach laufen bleiben und es wäre trozdem entkoppelt.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Markus Bloch

Zitat von: Reinerlein schrieb am Di, 12 Februar 2013 17:05Hi Markus,

wir hatten ja schon per PN Kontakt zu dem Thema...

Besteht denn in deiner Anwendungsstruktur die Möglichkeit die Thread-Beendigung zu verhindern?

Ich habe meinen Code für Sonos ja auch so umgestellt, dass ich denselben Thread immer wieder verwende, und die notwendigen Informationen und Aufträge in beiden Threads synchronisiere bzw. per Signalling und Queues transportiere.
Eine Baustelle habe ich da aber auch immer noch, mal schauen, was ich damit mache :-)

Vielleicht wäre das auch ein Ansatz bei dir. Allgemein wird das in den Perl-Foren, die sich mit Threading beschäftigen, auch empfohlen, da das Erzeugen eines Threads ja sehr Zeitaufwändig ist. Leider kann man es nur nicht immer so umsetzen (man kann ja z.B. keine Objekte transportieren o.ä.).

Grüße Reinerlein

Hallo Reinerlein,

dazu muss man erstmal 2 Sachen trennen.

1. PRESENCE ist ein völig normales FHEM Modul was so an sich erstmal keinerlei Threading oder dergleichen nutzt, bzw. steuert. Es verwendet das Modul Blocking.pm (welches von Rudi stammt) um einen zeitintensiven Aufruf von FHEM zu entkoppeln und dabei zu vermeiden, dass dieses stehen bleibt.

2. Blocking.pm ist ein Modul, welches eine übergebene Funktion abarbeiten soll, ohne FHEM dabei lahm zu legen. Dazu führt dieses Modul einen Fork durch (es wird ein zweiter Prozess erstellt, welcher eine 1:1 Kopie des Mutterprozesses ist). Dieser Fork-Prozess führt umgehend die gewünschte Funktion aus (bei PRESENCE den jeweiligen Test: Ping, FritzBox, Bluetooth) und gibt das Ergebniss über einen vorher erzeugten (oder bereits bestehenden) Telnet Socket an den Mutter-Prozess zurück.

Es wurde dabei diese Methode gewählt, da diese unter jedem Linux-System (egal welcher Platform) und auf allen FritzBoxen funktioniert gewählt.

Windows stellt hierbei eine Sonderlocke da, da "Forking" aus der Unix-Welt kommt: Da Windows kein Forking ermöglicht, erzeugen die meisten Perl-Interpreter unter Windows im Hintergrund einen neuen Thread, der sich (theoretisch) so verhalten soll, wie ein Fork-Child in der Unix-Welt.

Das ist allerdings leider nicht wirklich der Fall, wie ihr ja bereits festgestellt habt, aufgrund einiger Unterschiede in der Behandlung von File-Descriptoren, etc. Dazu kommen dann noch die eine oder andere Spezialität im Umgang mit seriellen Devices unter Windows in Perl (Da der Fehler ja nur bei einer CUL auftritt, aber nicht bei anderen File-Handles).

Aufgrund dessen, kam mein Vorschlag unter Windows einen Fork-Child mittels threads->exit(); zu beenden um ein Schließen der File-Descriptoren zu verhindern. Allerdings scheint dies nicht zu greifen.

In der ActivePerl-Dokumentation steht zum Thema "fork()" folgender Absatz:

On some operating systems, notably Solaris and Unixware, calling exit() from a child process will flush and close open filehandles in the parent, thereby corrupting the filehandles. On these systems, calling _exit() is suggested instead. _exit() is available in Perl through the POSIX module. Please consult your systems manpages for more information on this.

Hier könnte man noch ausprobieren den Fork-Child mittels POSIX::_exit(); zu beenden. Ich glaube mich aber erinnern zu können, dass dieses Modul bei ActivePerl nicht direkt mit dabei ist. Allerdings nutze ich Perl unter Windows leider nicht, evtl. hat hier jemand mehr Erfahrungen.

Ich hatte Rudi bereits vorgeschlagen das Modul Blocking.pm auf die verwendung von Threads (inkl. Thread::Queue) umzustellen. Dies hatte er aber (zurecht) verweigert, da dies unter FritzBoxen nicht funktionieren würde.

Ich hatte bereits mehrere Windows-spezifische Änderungen an Blocking.pm an Rudi herangetragen, welche er auch alle umgesetzt hat.

Leider kann ich da auch nicht wirklich helfen, da ich keinen CUL an Windows mit FHEM betreibe.

Viele Grüße

Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Markus Bloch

Zitat von: justme1968 schrieb am Di, 12 Februar 2013 17:10ein vorschlag in eine ähnliche richtung: wie wäre es den das ping über den presenced zu machen? der könnte einfach laufen bleiben und es wäre trozdem entkoppelt.

gruss
  andre
Hi Andre,

prinzipiell währe das durchaus möglich. Ich weis allerdings nicht, ob der presenced auch unter Windows läuft (was ja hier aktuell das Hauptproblem ist).

Viele Grüße

Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Markus Bloch

Hallo ChrisD

Zitat von: ChrisD schrieb am Di, 12 Februar 2013 11:18Hallo,

Ich habe deine Änderung eingespielt. Leider hat der Patch nicht den gewünschten Effekt. In meine Config-Datei habe ich:

define CHK_P1 PRESENCE lan-ping 192.168.0.100 15
attr CHK_P1 disable 1


Ich habe einige Log-Aufrufe in 73_PRESENCE hinzugefügt und festgestellt dass beim Aufruf von PRESENCE_Define Disable noch undefiniert ist. Erst 2s später wird Disable über PRESENCE_Attr gesetzt.

Die 2s Verzögerung kommen übrigens aus der Funktion InternalTimer. Diese blockiert fhem komplett da zum Zeitpunkt des Aufrufes aus PRESENCE_Define $init_done=0 und $waitIfInitNotDone=1 ist. Der Aufruf von InternalTimer aus der _Define-Funktion scheint mir keine gute Idee. Gibt es keine Möglichkeit global:INITIALIZED auszuwerten und erst hierüber die PRESENCE-Funktion zu starten ?

Grüsse,

ChrisD

Danke, das du mich darauf aufmerksam gemacht hast. Ich habe dies geändert. Als ich mit der Modul-Programmierung angefangen hatte, war mir nicht ganz klar, was dieser Parameter zu bedeuten hatte und wofür man den benötigt. Ich hab $waitIfInitNotDone auf 0 gesetzt um eine Blockierung hier zu verhindern.

Aus dem Wiki geht nicht hervor wie dieser Parameter genau zu verwenden ist.

Viele Grüße

Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

ChrisD

Hallo,

So weit ich die Dokumentation (und den Code) verstanden habe ist presenced.pl nur für Bluetooth-Scans. Somit ist es keine Lösung für lan-ping.

Das Problem was ich im letzten Beitrag (Di, 12 Februar 2013 11:18) beschrieben habe hat nicht mehr direkt mit dem ursprünglichen Problem zu tun, es tritt auch unter Linux auf. Soll ich dafür einen neuen Thread beginnen ?

Grüße,

ChrisD