HMCCURPC - Inkompatibilität mit HUEBridge (JSON)

Begonnen von EfkaPE, 01 August 2017, 15:10:42

Vorheriges Thema - Nächstes Thema

Barit

Yeah!
JSON::XS deinstallieren hat tatsächlich geklappt. Obwohl es mit einem einfachen
sudo apt remove libjson-xs-perl
bei mit nicht geklappt hat, da ich das Modul auch noch mit CPAN installiert bzw aktualisiert hatte.
Aber mit cpanminus konnte ich dann auch das mit CPAN installierte Modul JSON::XS entfernen:
sudo cpanm --uninstall JSON::XS

Danach wieder auf den externen RPC gewechselt und fhem neu gestartet, et voila! Keine JSON-Probleme mehr und alle fhem-Module laufen trotzdem noch.  :D
Auch wenn das "nur" ein Workaround ist: Solange kein anderes Programm JSON::XS benötigt kann ich damit gut leben.

Danke zap, dass du da dran geblieben bist!


justme1968

shared memory geht auch zwischen prozessen. mit den gleichen problemen bezüglich locking und semaphoren wie sonst auch.

warum sockets nciht schnell genug sind verstehe ich auch nicht. wenn man non blocking arbeitetet und auf der schreibenden seite buffer sollte das eigentlich funktionieren.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

zap

#32
Zitat von: herrmannj am 06 Oktober 2017, 18:33:18
Fork verwendet copy on write. Das ist was anderes.
Shared memory läuft nicht mit fork.

Das mit den Write errors bei sockets verstehe ich nicht. Non blocking socket, select, bei e would block in einen Puffer schreiben.

Bei Fork wird der komplette Prozess geklont inkl. Memory. Bei Threads wird der Speicher innerhalb des Parent-Prozesses gedoppelt (also im gleichen Speicherraum). So zumindest die Erklärung im Perl Thread Tutorial.

Ja das mit den Write Errors hat mich auch ziemlich viele Nerven gekostet. Ich habe gemeinsam mit Boris mit dem SubProcess.pm experimentiert. Die Abfrage auf Would Block hat auch in den meisten Fällen funktioniert. Aber nicht immer. Manchmal kam kein Would Block und das Schreiben ging trotzdem schief bzw. es wurde Erfolg gemeldet und die Daten kamen nie in Read() an. Insbesondere, wenn bei der Initialisierung der Verbindung zur CCU diese ihre ganze Konfiguration schickt (>300 Kb).

Ich möchte da keinen Aufwand mehr reinstecken und bei Threads bleiben. Bevor ich nochmal mit Fork rumfrickle wechsle ich eher zu OpenHab oder IOBroker. Ich habe schon einige ähnliche Programme in C/C++ geschrieben. Da hatte ich nie diese Probleme wie mit Perl.

Aber Deine Idee, zunächst einen speichermäßig kleinen Prozess zu starten und von dort dann die Threads werde ich mir nochmal anschauen.

@Barit: Aus eigenem Interesse. Nachdem ich das neue Raspbian installiert hatte, wollte ich das Ding auch in Betrieb nehmen.


2xCCU3 mit ca. 100 Aktoren, Sensoren
Entwicklung: FHEM auf Proxmox Debian VM
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: HMCCU, (Fully, AndroidDB)

justme1968

jede 'moderne' fork implementierung arbeitet mit copy on write damit z.b. bei einem direkt nachfolgenden exec nicht umsonst kopiert wird.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

dev0

@zap:
Da 50+ offizielle FHEM Module decode_json() verwenden und (teilweise?) von dem "Bug" betroffen sind, möchte ich Dich bitten das Problem zu lösen.

Im Wiki zu beschreiben, dass es zu Problemen kommen kann, ist mAn nicht die Lösung, wenn andere Module davon in Mitleidenschaft gezogen werden und gar nicht mehr funktionieren. Das wirft zum einen kein gutes Licht auf FHEM im Allgemeinen und verursacht zum anderen Supportaufwand bei weiteren Maintainern.

Wenn dieses Problem, das augenscheinlich durch Dein externes HMCCU RPC Modul ausgelöst wird, erst einmal nicht zu lösen ist, dann wäre es aus meiner Sicht angebracht, dass Du solange Dein Modul nur noch mit dem internen RPC Server anbietest und die Nutzung des externen RPC Servers unterbindest (zumindest würde ich so handeln). Auch die Empfehlung aus dem HMCCU Wiki, JSON::XS zu deinstallieren, empfinde ich als nicht angemessen, da dadurch dann 50+ andere Module langsamer arbeiten, mit dem einzigen Ziel Dein HMCCU Modul zu beschleunigen. Abgesehen davon, dass ein Anwender das Problem erst einmal erkenen muss...

Aktueller Anlass für mein Posting: https://forum.fhem.de/index.php/topic,81840

zap

Lies bitte mal diesen Post von mir:

https://forum.fhem.de/index.php/topic,74943.msg695487.html#msg695487

In neueren Versionen von Json::xs wurde etwas geändert. Dies bedingt, dass eine bestimmte Option gesetzt werden muss. Wann Json::xs verwendet wird, ist nicht klar dokumentiert. Man kann das nur erzwingen, wenn man das Modul deinstalliert.
Es ist kein Problem meines Moduls sondern ein Problem, das in der Konstellation Json, Threads, shared Memory auftritt.
2xCCU3 mit ca. 100 Aktoren, Sensoren
Entwicklung: FHEM auf Proxmox Debian VM
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: HMCCU, (Fully, AndroidDB)

dev0

Das heißt im Umkehrschluss, dass aus Deiner Sicht für die korrekte Funktion von FHEM, JSON::XS nicht installiert sein darf oder Entwickler aller anderen Module nur noch die OO Variante von JSON verwenden dürfen.

Würdest Du das dann bitte in der Developer Area verkünden, damit nicht noch andere Entwickler auf die absurde Idee kommen, JSON "einfach so" zu verwenden und die, die es verwenden, es ändern können?

CoolTux

@zap
Ich befürchte so einfach wird das nicht zu lösen sein.
Die User sehen immer gerne nur das Offensichtliche. Lass mich Dir kurz das Offensichtliche erklären. Ein User hat Probleme mit 2-3 Modulen wegen Fehlermeldungen. Er meldet sich bei den Autoren und bekommt als Antwort von jedem Autor gleich, schalte den internen RPC Server ein. Und oh siehe da, es geht wieder. Also kommt der User zurück zu Dir und fragt was da los sei. Er habe nur bei Deinem Modul etwas geändert und schon geht alles wieder. Es muss also an Deinem Modul liegen. So sehen User das Offensichtliche.
Also lass uns doch einfach zusammen versuchen eine für alle brauchbare Lösung zu finden. Hier sind so viele gute Perlexperten, da kann es ja nicht so schwer sein.


Ansonsten befürchte ich das Du im schlimmsten Fall gebeten wirst Deine Module nach Contrib zu verlegen und sie somit nicht mehr offiziellen Status haben, da sie zu anderen offiziellen Modulen inkompatibel sind.




Grüße
Leon
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

zap

Die auftretenden Fehler in der Kombi Json::xs und Threads sind mE nur der Anfang. Zunächst werden jetzt mal alle Module auf die schwarze Liste gesetzt, die Threads verwenden. Das wäre dann HMCCURPC, SONOS und vielleicht noch das eine oder andere. Wenn dann weitere Probleme auftreten, werden dann noch andere Module ,,gebannt". Und alles nur, weil sich Entwickler nicht damit abfinden wollen, dass sich das Verhalten bzw die Anwendung der JSON Module in Perl geändert hat. Was kann ich denn dafür? Ich nutze Threads gemäß der Spezifikation.
Ich habe jedenfalls weder Lust noch Zeit, einen Fehler zu beheben, der keiner ist sondern nur die Änderung eines APIs.

@cooltux: bist du der Svn Verantwortliche, der diese Entscheidung für/gegen SVN/contrib trifft? Dachte eigentlich, das wären andere. Wenn dem also nicht so ist, kannst du dir die Drohungen bitte schenken. Falls es wirklich soweit kommen sollte, richte och eben eine github Update Source ein und gut. Und gezwungen HMCCURPC zu verwenden, wird ja jetzt auch keiner.
2xCCU3 mit ca. 100 Aktoren, Sensoren
Entwicklung: FHEM auf Proxmox Debian VM
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: HMCCU, (Fully, AndroidDB)

CoolTux

#39
Mal langsam. Ich habe hier mit gar nichts gedroht. Ich habe meine persönliche Befürchtung zum Ausdruck gebracht. Das war alles.

Das das selbe Problem bei Sonos auch auf tritt ist mir persönlich neu, habe da noch gar nichts von gehört.

Alles was ich wollte ist eine Lösung anstreben. Wegen meiner können wir das auch so belassen wie es ist. Passt schon.

Was wäre Deiner Meinung nach denn zu tun? Also von den Developer deren Module nun Fehler werfen wenn HMCCURPC extern geladen wird.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

zap

Nochmal, das Zitat aus der offiziellen JSON Doku zu diesem Thema:

... but future versions might/will likely upgrade to the newer RFC as default format, so you are advised to check your implementation and/or override the default with ->allow_nonref (0) to ensure that future versions are safe.

Eigentlich unmissverständlich: das Todo liegt auf Seiten der Anwender der Json Module.
2xCCU3 mit ca. 100 Aktoren, Sensoren
Entwicklung: FHEM auf Proxmox Debian VM
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: HMCCU, (Fully, AndroidDB)

CoolTux

Also sollte ich in meinen Modulen in Zukunft JSON so einbinden?


my $json = JSON::XS->new->allow_nonref;

   $text = $json->encode ($data);
   $data = $json->decode ($text);
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

justme1968

immer wieder auf allow_nonref zu verweisen geht leider am thema vorbei.

zum einen:
das
ZitatDue to security concerns, JSON::XS will not allow scalar data in JSON texts by default - you need to create your own JSON::XS object and enable allow_nonref:
bezieht sich auf so etwas: encode_json("Hello, World!"); hier wird direkt ein string übergeben statt einer hash ref bzw. ode array ref. diesen fall kann man mit allow_nonref erlauben. entsprechend bei decode. korrekt wäre z.b. encode_json(["Hello World!"]);und das muss nach wie vor ohne allow_nonref gehen.

zum anderen:
die json doku sagt ganz klar:
Zitatdecode
The opposite of encode_json: expects an UTF-8 (binary) string and tries to parse that as an UTF-8 encoded JSON text, returning the resulting reference. Croaks on error.

Zitatdecode_json
The opposite of encode_json: expects an UTF-8 (binary) string and tries to parse that as an UTF-8
encoded JSON text, returning the resulting reference. Croaks on error.

d.h. beide erwarten einen string und liefern eine referenz zurück. der sinn von encode und decode ist doch genau zwischen einer perl hash oder array ref und einem string den man dann verschickt hin und her zu übersetzen. und genau das geht nicht mehr sobald die externe rpc version verwendet wird.


um es noch mal zusammen zu fassen:
- der fall der mit allow_nonref erlaubt wird ist für unser problem nicht relevant.
- das problem ist das korrekter code plötzlich nicht mehr geht sobald der externe rpc server verwendet wird

d.h. das problem ist nicht auf seiten der 50 module die funktionieren so lange der externe rpc server nicht mit im spiel ist.

mehr details gibt es auch hier: https://forum.fhem.de/index.php/topic,74943.msg693395.html#msg693395 noch mal.

ganz unabhängig davon: auf andere module zu verweisen die threads verwenden geht auch am thema vorbei zumindest so lange wie diese keine probleme machen.

es geht hier doch garnicht ums drohen sondern darum eine lösung für ein problem zu finden das tatsächlich immer wieder hier im forum aufschlägt.und auch wenn wir noch nicht wissen wie und warum der externe rpc server dazu führt ist er definitiv beteiligt. vermutlich sogar ursächlich. ganz ohne schuld hin und her zu schieben. auch wenn die meisten die doku nicht lesen wäre es vielleicht hilfreich dort und im log eine meldung unterzubringen die auf die json probleme hinweist.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

CoolTux

Danke Andre,

Alles was ich wollte war ja nur eine gemeinsame Lösung anstreben. Nach dem ich mir nun mehrere Meinungen durch gelesen habe und mir mehr Infos in einem persönlichen Telefonat geholt habe, bin ich zu einem persönlichen Entschluss zu diesem Thema gekommen.
Ich werde diesen hier nicht mitteilen. Für mich hat sich das bis auf weiteres hier erstmal erledigt. Sollte die Mehrheit beschließen das die Anwendung von JSON geändert werden muss, so habe ich kein Problem damit das in meinen Modulen um zu setzen.


Grüße
Leon
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

zap

Zitat von: justme1968 am 01 Januar 2018, 15:43:03
immer wieder auf allow_nonref zu verweisen geht leider am thema vorbei.

Beim OO Call eigentlich nicht. Weil das geht zwar nicht:
my $json = JSON->new;
my $text = $json->encode(["Hello World!"]);

aber das:
my $json = JSON->new->allow_nonref;
my $text = $json->encode(["Hello World!"]);


Zitat
zum anderen:
die json doku sagt ganz klar:
d.h. beide erwarten einen string und liefern eine referenz zurück.

Stimmt teilweise. Im Beispiel zu encode steht ganz open bei CPAN, dass eine Hash- oder Array-Ref erwartet wird. Bei decode hingegen ein string. In besagtem Beispiel wird auch bei OO allow_nonref verwendet. Bei nicht OO müsste es aber zumindest bei decode wie von Dir beschrieben funktionieren. Witzigerweise kommt die Fehlermeldung sogar, wenn man der encode Funktion wie in der Fehlermeldung gewünscht eine Hash- oder Array-Ref übergibt.

Mittlerweile gibt es mit mit Cpanel::JSON::XS einen Fork von JSON::XS wegen der vielen Bugs in JSON::XS und weil der Maintainer von JSON::XS anscheinend beratungsresistent ist. Wird halt (bis jetzt) nur verwendet, wenn man es explizit einbindet. JSON selbst verwendet nach wie vor JSON::XS, sofern es da ist.

Hier mal noch ein Testprogramm, das den Fehler provoziert, sofern man die Create Thread Zeile auskommentiert. Das Problem ist damit leicht auf das Erzeugen eines Threads zurückzuführen:

#!/usr/bin/perl

use strict;
use warnings;
use JSON;
use threads;
use threads::shared;

sub th {   }

# Naechste Zeile provoziert JSON-Fehlermeldung
# threads->create(\&th)->join();

# Naechste Zeile verhindert JSON-Fehlermeldung auch bei erzeugtem Thread
# my $json = JSON->new->allow_nonref;

my $json = JSON->new;
my $text = $json->encode(["Hello World!"]);
print "$text\n";


Interessant ist, dass bei Einbindung von threads.pm mit use der Fehler nicht auftritt. Erst das Erzeugen eines Threads führt dazu. Nun verwendet SONOS zwar auch Threads, diese werden jedoch aus einem geforkten Subprozess heraus gestartet. Daher tritt der Fehler dort nicht auf (s. testprog unten). Es gibt noch ein paar andere Module, die Threads verwenden. Je nach Art des Thread-Starts müsste der Fehler dort auch auftreten.

Hier ein Beispiel, bei dem der Thread in einem Subprozess gestartet wird. Der JSON Fehler tritt (auch ohne allow_nonref) nicht auf:


#!/usr/bin/perl

use strict;
use warnings;
use JSON;
use threads;
use threads::shared;

sub th { print "Thread!\n";  }

my $pid = fork ();
if (!defined ($pid)) {
        print "Can't fork\n";
}
elsif ($pid == 0) {
        threads->create(\&th)->join();
        exit (0);
}

my $json = JSON->new;
my $text = $json->encode(["Hello World!"]);

print "$text\n";


Fazit: JSON::XS und Threads tun nicht zusammen. Mögliche Lösungen:

- Keine FHEM-Module verwenden, die Threads nutzen und diese im Hauptprozess starten
- JSON::XS deinstallieren
- In FHEM-Modulen, die JSON verwenden, die OO-Version verwenden und allow_nonref setzen
- In FHEM-Modulen, die JSON verwenden, statt JSON::XS explizit Cpanel::JSON::XS verwenden (nicht getestet, löst aber angeblich das Problem auch)
- Hoffen, dass irgendwann JSON::XS durch Cpanel::JSON::XS ersetzt wird
2xCCU3 mit ca. 100 Aktoren, Sensoren
Entwicklung: FHEM auf Proxmox Debian VM
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: HMCCU, (Fully, AndroidDB)