FHEM Forum

FHEM - Entwicklung => FHEM Development => Thema gestartet von: Loredo am 26 Mai 2016, 20:05:04

Titel: Logschwelle in DevIo.pm
Beitrag von: Loredo am 26 Mai 2016, 20:05:04
Hallo Rudi,


spricht etwas dagegen die Logschwelle bei den Log3 Anweisungen in DevIo.pm zu erhöhen?
Siehe https://forum.fhem.de/index.php/topic,15024.msg454697.html#msg454697



Gruß
Julian
Titel: Antw:Logschwelle in DevIo.pm
Beitrag von: rudolfkoenig am 29 Mai 2016, 11:19:38
Ungern.
Du koenntest im Modul in ONKYO_AVR_Ready/ONKYO_AVR_Reopen das verbose Attribut fuer die Instanz temporaer hochsetzen.
Alternativ, falls weitere Entwickler dafuer plaedieren, spendiere ich ein $quiet Parameter der Funktion DevIo_OpenDev
Titel: Antw:Logschwelle in DevIo.pm
Beitrag von: Loredo am 05 Juni 2016, 11:36:04
Ich denke ich habe es jetzt anders/besser gelöst. Ist nicht so leicht durchzusteigen um zu verstehen, wie man optimalerweise prüft, ob eine Verbindung bei Leerlauf noch besteht/funktioniert. Habe das aber recht zufriedenstellend hinbekommen jetzt.


Gruß
Julian
Titel: Antw:Logschwelle in DevIo.pm
Beitrag von: Markus Bloch am 05 Juni 2016, 14:39:03
Ganz einfach:

if($hash->{FD})
{
    # Verbindung besteht noch
}
else
{
    # Verbindung steht nicht
}


So prüf ich das immer, ob eine Verbindung von DevIo noch besteht.

Gruß
Markus
Titel: Antw:Logschwelle in DevIo.pm
Beitrag von: Loredo am 05 Juni 2016, 14:51:37
Ist das zuverlässig genug, ohne dass man eine Testnachricht schickt und auf eine Rückantwort prüft? Soweit ich das gesehen habe wird ja DevIo_Disconnected() erst aufgerufen, wenn es quasi schon zu spät ist. Der Verbindungsverlust sollte aber auch auffallen, wenn normalerweise keine Daten übertragen werden. Bin mir nicht sicher, ob der File Descriptor nicht erhalten bleibt, obwohl die TCP Session eigentlich tot ist...
Titel: Antw:Logschwelle in DevIo.pm
Beitrag von: Markus Bloch am 05 Juni 2016, 14:55:50
Sollte die TCP Session hängen geblieben sein, weil bspw die DSL Verbindung weggefallen ist, oder die Zielmaschine ein Stromausfall hat, etc. Merkt das DevIo natürlich nicht sofort. Dann ist der FD natürlich noch offen, obwohl die gegenseite nichts mehr senden kann. Erst, wenn man etwas sendet und die Gegenseite nicht antwortet, merkt der TCP Stack dies und macht die Verbindung mit EOF zu, woran dann DevIo auch erkennt, dass die Verbindung unterbrochen ist und demzufolge den FD zumacht und $hash->{FD} löscht.

Aus diesem Grund arbeitet DevIo bei TCP mit Keep-Alives, aber auch die benötigen etwas Zeit um eine tote Verbindung zu erkennen, da die nicht jede Sekunde laufen.

Gruß
Markus
Titel: Antw:Logschwelle in DevIo.pm
Beitrag von: Loredo am 05 Juni 2016, 15:13:53
Zitat von: Markus Bloch am 05 Juni 2016, 14:55:50
Aus diesem Grund arbeitet DevIo bei TCP mit Keep-Alives, aber auch die benötigen etwas Zeit um eine tote Verbindung zu erkennen, da die nicht jede Sekunde laufen.


Dass hier ein Timeout notwendig ist, ist ja egal. Das habe ich in der connectionCheck Methode ja auch. Aber natürlich will ich nichts redundantes haben. Wo ist denn bei einem Verbindungsverlust der Wiedereinstieg von $conn? Ich kann nicht sehen, dass der FD gelöscht würde oder gar die disconnect() Funktion aufgerufen würde (letzteres wäre ja extrem wünschenswert). Da könnte ich mir natürlich eine Menge unnützer Workarounds im Modul sparen.
Titel: Antw:Logschwelle in DevIo.pm
Beitrag von: rudolfkoenig am 05 Juni 2016, 19:52:33
ZitatDass hier ein Timeout notwendig ist, ist ja egal.
Das default Timeout unter Linux fuer SO_KEEPALIVE ist ca 2 Stunden.

ZitatWo ist denn bei einem Verbindungsverlust der Wiedereinstieg von $conn?
Falls SO_KEEPALIVE zuschlaengt, dann wird via select ReadFn aufgerufen, wo ueblicherweise DevIo_SimpleRead aufgerufen wird.
DevIo_SimpleRead kriegt undef oder 0 bei sysread, woraufhin sie DevIo_Disconnected aufruft. Ab hier ruft fhem.pl alle 5 Sekunden ReadyFn auf, was wiederum ueblicherweise ein DevIo_OpenDev versucht.
Titel: Antw:Logschwelle in DevIo.pm
Beitrag von: Loredo am 05 Juni 2016, 19:59:06
Danke Rudi für die Erklärung! Damit ist mir der Fluss nun viel klarer.

Zitat von: rudolfkoenig am 05 Juni 2016, 19:52:33
Das default Timeout unter Linux fuer SO_KEEPALIVE ist ca 2 Stunden.

Das klingt als wenn es eigentlich eher nutzlos ist, nach 2 Stunden braucht man auch nicht mehr wissen, dass eine Verbindung weg ist. Kann man das Timeout nicht niedriger setzen? Ansonsten bräuchte man SO_KEEPALIVE ja gar nicht erst setzen.
Titel: Antw:Logschwelle in DevIo.pm
Beitrag von: rudolfkoenig am 05 Juni 2016, 20:29:33
ZitatDas klingt als wenn es eigentlich eher nutzlos ist
Habs auch nur vollstaendigkeit-/einfachheits-halber eingebaut, ist gar nicht so lange her. Immerhin ist es besser nach 2 Stunden zu wissen, als nach 2 Wochen zu vermissen. Ich meine SO_KEEPALIVE kann man nur Systemweit aendern mit irgendeinem echo > /sys/... und das erzeugt doch relativ viele "ping" Pakete. Wenn jemand doch was einbaubares findet, her damit.
Titel: Antw:Logschwelle in DevIo.pm
Beitrag von: Loredo am 05 Juni 2016, 21:26:27
Ich hatte es jetzt einmal hiermit versucht, jedoch auf OSX und Linux keinen Erfolg damit  :-\


if ( defined($conn) ) {
    my $idle  = 60;
    my $cnt   = 6;
    my $intvl = 5;

    $conn->setsockopt( SOL_SOCKET, SO_KEEPALIVE, 1 )
      or Log3 $name, 4, "Can't set SO_KEEPALIVE: " . $!;

    $hash->{KEEPALIVE} =
      $conn->getsockopt( SOL_SOCKET, SO_KEEPALIVE );

    $conn->setsockopt( IPPROTO_TCP, TCP_KEEPIDLE, $idle )
      or Log3 $name, 4, "Can't set TCP_KEEPIDLE: " . $!;

    $hash->{KEEPIDLE} = $conn->getsockopt( IPPROTO_TCP, TCP_KEEPIDLE );

    $conn->setsockopt( IPPROTO_TCP, TCP_KEEPCNT, $cnt )
      or Log3 $name, 4, "Can't set TCP_KEEPCNT: " . $!;

    $hash->{KEEPCNT} = $conn->getsockopt( IPPROTO_TCP, TCP_KEEPCNT );

    $conn->setsockopt( IPPROTO_TCP, TCP_KEEPINTVL, $intvl )
      or Log3 $name, 4, "Can't set TCP_KEEPINTVL: " . $!;

    $hash->{KEEPINTVL} = $conn->getsockopt( IPPROTO_TCP, TCP_KEEPINTVL );
}





Die Meldung lautet "Protocol not available". Das Protokoll IPPROTO_TCP scheint aber zu stimmen, es ist wohl eher die Option, die es so nicht gibt. Eine Recherche nach einer anderen Bezeichnung war ohne Ergebnis.


Auch die explizite Angabe von Proto = "tcp" bei der Erstellung des Sockets hatte ich probiert.
Titel: Antw:Logschwelle in DevIo.pm
Beitrag von: zap am 10 Juni 2016, 07:29:12
Zitat von: Loredo am 05 Juni 2016, 21:26:27
Die Meldung lautet "Protocol not available". Das Protokoll IPPROTO_TCP scheint aber zu stimmen, es ist wohl eher die Option, die es so nicht gibt. Eine Recherche nach einer anderen Bezeichnung war ohne Ergebnis.


Auch die explizite Angabe von Proto = "tcp" bei der Erstellung des Sockets hatte ich probiert.

Versuche es mal so:


my $protocol = getprotobyname ("tcp");