98_update.pm (Retry bei Verbindungsproblemen)

Begonnen von dominik, 11 August 2015, 20:38:31

Vorheriges Thema - Nächstes Thema

dominik

Hallo zusammen,

ich habe ein Update für das 98_update.pm Modul erstellt welches folgende Funktionen integriert:
- Wenn HttpUtils_BlockingGet fehl schlägt, wird 20x versucht dies zu wiederholen.
- Vor jeder Wiederholung ist ein sleep(2) eingebaut um etwas zu warten, da ich von einem temporären Problem ausgehe.
- Bei jedem Fehler wird ein Log Entry dazu geschrieben mit der Fehlerbeschreibung aus $err.

Wäre super wenn der Code seinen Weg ins Repository findet bzw. wenn etwas noch nicht zum Coding Style passt ich Feedback dazu erhalte.

Diff
--- /opt/fhem/FHEM/98_update.pm 2015-08-17 21:25:28.252974821 +0200
+++ /opt/fhem/FHEM/98_update.pm.bak     2015-08-17 21:17:10.799091282 +0200
@@ -371,8 +371,18 @@
upd_getUrl($)
{
   my ($url) = @_;
+  my ($errcount) = 0;
+  my ($errmax) = 0;
   $url =~ s/%/%25/g;
+
   my ($err, $data) = HttpUtils_BlockingGet({ url=>$url });
+  while($err && $errcount<$errmax) {
+    uLog 2, "Retry $errcount/$errmax $url due to error: ".$err;
+    $errcount++;
+    sleep(2);
+    ($err, $data) = HttpUtils_BlockingGet({ url=>$url });
+  }
+
   if($err) {
     uLog 1, $err;
     return "";


Hier der Ursprungsthread dazu:
http://forum.fhem.de/index.php/topic,39837.0.html

Gruß
dominik
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

rudolfkoenig

Welches Problem wird damit geloest?
Und warum genau 2s sleep und 20-mal?

dominik

Problem: Update schlägt fehl, weil Verbindung immer wieder Probleme macht (aktuell unerklärlich, da ping funktionierte). In so einem Fall ist KEIN update möglich. Fhem bricht andauernd ab und ich muss wieder bei 0 starten.

Folgende Fehlermeldungen erhielt ich andauernd:
2015.08.09 11:25:03 1: UPD www/images/fhemSVG/rc_YELLOW.svg
2015.08.09 11:25:03 1: UPD www/images/fhemSVG/rc_dot.svg
2015.08.09 11:25:04 1: http://fhem.de/fhemupdate/www/images/fhemSVG/rc_dot.svg: Can't connect(1) to http://fhem.de:80: IO::Socket::INET: connect: No route to host
2015.08.09 11:25:18 1: UPD www/images/default/10px-kreis-gelb.png
2015.08.09 11:25:18 1: UPD www/images/default/10px-kreis-gruen.png
2015.08.09 11:25:18 1: UPD www/images/default/10px-kreis-rot.png
2015.08.09 11:25:18 1: UPD www/images/default/1px-spacer.png
2015.08.09 11:25:19 1: UPD www/images/default/FS20.off.png
2015.08.09 11:25:19 1: http://fhem.de/fhemupdate/www/images/default/FS20.off.png: Can't connect(1) to http://fhem.de:80: IO::Socket::INET: connect: No route to host
2015.08.09 11:25:29 1: UPD www/images/default/10px-kreis-gelb.png
2015.08.09 11:25:29 1: UPD www/images/default/10px-kreis-gruen.png
2015.08.09 11:25:29 1: UPD www/images/default/10px-kreis-rot.png
2015.08.09 11:25:29 1: http://fhem.de/fhemupdate/www/images/default/10px-kreis-rot.png: Can't connect(1) to http://fhem.de:80: IO::Socket::INET: connect: No route to host


Hatte nebenbei auch einen ping laufen, der ohne Probleme funktionierte. Da ich keine Möglichkeit hatte FHEM zu aktualisieren (tagelang probiert, immer wieder mit auch Router Neustart gemacht) versucht ich eine andere Lösung zu finden. Daher entstand dieser Patch.

Die 2s sleep sollten nur dazu da sein, dass der Http Request nicht sofort nochmals gemacht wird - da ja aktuell ein Problem mit der Verbindung besteht. Eventuell genügt auch 1s.
Als ich die Funktionalität das erste Mal testete, hatte ich teilweise bis zu 10 Http Requests die nicht funktionierten. Daher habe ich "sicherheitshalber" 20x genommen. Ich weiß, das ist nichts was irgendwo hergeleitet ist, aber mit irgendwas musste ich starten.

Die einzige Frage die sich in diesem Fall stellt, ist wie lange man nun wirklich "wartet" bis die Verbindung wieder steht.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

Wernieman

Da könnte man sich auch bei anderen Projekten mit Update per Internet informieren.

z.B.
Gentoo eselect macht es 3 Mal mit 1 sec. "Pause"
debian/ubuntu apt-get probiert es auch mehrmals, gibt es nur nicht aus
......

Da es auch bei einem "guten" Anschluß zu Problemen kommen kann, würde ich normalerweise auf 3 Wiederholungen mit 1sec Pause gehen.

Nur mal meine 2cent aus Erfahrungen im Netzwerkbereich ..
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

dominik

Die andere Frage wäre, ob man nicht direkt in den HttpUtils.pm ansetzen sollte? Schlussendlich soll ja davon jeder profitieren und nicht nur 98_update.pm.

Ein großer Unterschied zu apt-get und eselect ist, dass diese Tools in vielen Fällen dort weitermachen wo der Verbindungsabbruch aufgetreten ist. update macht das nicht, es beginnt wieder bei 0 und damit war es bei mir unmöglich das Update durchzuführen.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

dominik

Hier ein Update für HttpUtils.pm

HttpUtils.pm.patch
364a365,382
> # Parameters same as HttpUtils_NonblockingGet with additional maxretries parameter
> # Returns (err,data)
> sub
> HttpUtils_BlockingGetWithRetries($)
> {
>   my ($hash) = @_;
>   my ($errcount) = 0;
>   my ($maxretries) = 20 if (!defined($hash->{maxretries}));
>   my ($err, $data) = HttpUtils_BlockingGet($hash);
>   while ($err && $errcount<$maxretries) {
>     $errcount++;
>     sleep(2);
>     ($err, $data) = HttpUtils_BlockingGet($hash);
>   }
>   return ($err, $data);
> }
>
> #################


Änderungen
- Neue Funktion HttpUtils_BlockingGetWithRetries hinzugefügt.
- Standardmäßig werden 20 Retries mit 2s Pause gemacht wenn die Funktion verwendet wird
- Parameter maxretries definiert die Anzahl der retries

Diese Funktion könnte dann in jedem Modul verwendet werden. Wenn es keine Einwände gibt, könnte man natürlich auch gleich die Funktion in HttpUtils_BlockingGet umbenennen und die aktuelle Funktion auf eine interne ändern, so das automatisch alle Module die neue Retry Funktionalität nutzen.

Was meint ihr? Welcher Weg ist der richtige?
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

celeritas

Interessant wäre dann zu einer möglichen Lösung wie der Benutzer sein Update lauffähig bekommt, damit er am Ende wieder einen sauberen Stand hat. Sozusagen einen Micro-Patch, den der Benutzer manuell ausführen muss mit einem kleinen How-To.

dominik

Zitat von: Celeritas am 13 August 2015, 12:50:56
Interessant wäre dann zu einer möglichen Lösung wie der Benutzer sein Update lauffähig bekommt, damit er am Ende wieder einen sauberen Stand hat. Sozusagen einen Micro-Patch, den der Benutzer manuell ausführen muss mit einem kleinen How-To.
Von How-Tos oder Micro-Patches die der User selber ausführen muss halte ich nichts. Das "Ding" (also FHEM  :) ) muss funktionieren und im best case mit so wenig wie möglich Aufwand in der Konfiguration. Vor allem bei einem HttpGet soll der User nichts machen müssen.

Da ich das Thema hier nicht untergehen lassen will, frage ich mich wie wir hier weitermachen? HttpUtils oder 98_update?
Wer trifft eigentlich bei FHEM die Design/Architektur Entscheidungen?
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

krikan

#8
ZitatDa ich das Thema hier nicht untergehen lassen will, frage ich mich wie wir hier weitermachen? HttpUtils oder 98_update?
Wer trifft eigentlich bei FHEM die Design/Architektur Entscheidungen?

Letztlich der Maintainer-> http://fhem.de/MAINTAINER.txt . Also der, der alles ausbaden muss.
Ansonsten bitte bedenken, dass hier keine Hauptamtlichen arbeiten. Darum mal abwarten...

celeritas

Zitat von: dominik am 13 August 2015, 18:57:54
Von How-Tos oder Micro-Patches die der User selber ausführen muss halte ich nichts. Das "Ding" (also FHEM  :) ) muss funktionieren und im best case mit so wenig wie möglich Aufwand in der Konfiguration. Vor allem bei einem HttpGet soll der User nichts machen müssen.

Würde ich dir im Normal-Fall zustimmen, jedoch gibt es im Moment genug Leute, die nicht in der Lage sind ein Update erfolgreich zu beenden. Somit kommt man um einen Workaround wohl nicht drum herum. Die Meldungen zu "Can't connect(1) to http://fhem.de:80: IO::Socket::INET: connect: timeout" werden ja immer mehr.

dominik

Ich wusste nicht, dass die Meldungen dazu in letzter Zeit mehr werden. Wenn dem so ist, dann sollten wir zügig eine Lösung implementieren.

Du hast Recht, dass auch meine Lösung nur ein Workaround ist. Die richtige Lösung wäre wohl ein Retry inkl. speichern des Fortschritts beim Update. So könnte man das Update immer wieder Fortsetzen und muss im Fehlerfall nicht von vorne beginnen. Irgendwann sollte es dann klappen.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

stromer-12

Ich hatte gestern auch nach langer Zeit ein Update gewagt. Auch ständig diese Abrüche. Habe dann mittels exclude sie Unterverzeichnisse und die einen Großteil der xx_yyyy.pm Dateien unterdrückt. Anschließend hatte er beim nächsten update mit Überprüfung der Dateigröße ohne exclude nur noch ein paar Dateien nachgezogen.

Gesendet von meinem GT-I9295

FHEM (SVN) auf RPi1B mit HMser | ESPLink
FHEM (SVN) virtuell mit HMLAN | HMUSB | CUL

dominik

Also ich denke, dass der Patch aus dem ersten Post vorerst mal eingespielt werden sollte. Damit ermöglicht man zumindest den Usern wieder das Update. Danach kann man sich Gedanken dazu machen, ob nicht doch die HttpUtils.pm den Retry Mechanismus erhalten soll.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

Puschel74

#13
Grad eben auf meinem RasPi wieder ein update gemacht und - klappt.
ZitatAlso ich denke, dass der Patch aus dem ersten Post vorerst mal eingespielt werden sollte.
Solange es keine Nebenwirkungen mit funktionierenden updates gibt.

Edith: Bitte nicht falsch verstehen.
Wenn es eine Lösung gibt dann bitte für alle und nicht erst
ZitatDanach kann man sich Gedanken dazu machen,
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

Icinger

ZitatWürde ich dir im Normal-Fall zustimmen, jedoch gibt es im Moment genug Leute, die nicht in der Lage sind ein Update erfolgreich zu beenden. Somit kommt man um einen Workaround wohl nicht drum herum.
Wozu workarounds?

Erstmal einfach ein
update 98_update.pm
reload 98_update
ausführen, dann kann man den Rest schon  mit dem "neuen" Modul machen.

lg, Ici
Verwende deine Zeit nicht mit Erklärungen. Die Menschen hören (lesen) nur, was sie hören (lesen) wollen. (c) Paulo Coelho