CoProcess Start bei init_done=0

Begonnen von dominik, 29 September 2020, 22:21:51

Vorheriges Thema - Nächstes Thema

dominik

Hallo,

wäre es möglich, dass man einen CoProcess::start() auch während dem Startup (init_done=0) zulässt? Ich habe nämlich Module die im Define den Prozess gestartet benötigen um das Define auszuführen. Wäre super wenn man folgende Zeile entfernen oder als Parameter deaktivieren könnte:
https://github.com/mhop/fhem-mirror/blob/master/fhem/FHEM/CoProcess.pm#L140

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

zap

#1
Ich denke auch, dass man die Entscheidung dem Entwickler überlassen kann, ob er das vor oder nach Abschluss der FHEM Initialisierung aufruft. Man muss natürlich wissen, was man tut. Ggf. fehlen vor dem init_done = 1 einige Attribute oder Devices, weil die Config noch nicht komplett abgearbeitet wurde.

Das könnte sonst schon zu unangenehmen Seiteneffekten führen.

Alternativ kannst Du natürlich auf CoProcess verzichten und einfach einen fork() nutzen oder z.B. SubProcess.pm verwenden.
2xCCU3, Fenster, Rollläden, Themostate, Stromzähler, Steckdosen ...)
Entwicklung: FHEM auf AMD NUC (Ubuntu)
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: FULLY, Meteohub, HMCCU, AndroidDB

dominik

Da hast du Recht mit den Seiteneffekten, aber das haben wir denke ich so oder so. Bei jedem Define müsste man nämlich in speziellen Fällen auf $init_done prüfen.

Also ich würde mich freuen wenn wir den Start mit einem Parameter forcieren könnten.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

justme1968

ich verstehe den grund nicht warum der start unbedint im define erfolgen muss und behaupte mal das stimmt nicht.

bei init_done = 0 ist fhem grundsätzlich in einem unfertigen und unbekannten zustand. unter anderem läuft die select loop noch nicht und man kann nicht auf mögliche probleme beim start reagieren. vor dem init_done fehlen definitiv alle attribute, readings und eventuell abhängige devices.

aus fhem heraus niemals direkt fork verwenden. wenn dann dann unbedingt fhemFork verwenden. das sorgt nach bestem wissen dafür das so weit aufgeräumt wird das unter anderem ein neustart möglich ist. beim normalen fork werden ressourcen dupliziert was sehr unangenehme nebeneffekte haben kann. also bitte das direkte fork nicht empfehlen.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

betateilchen

Zitat von: justme1968 am 26 November 2020, 18:24:49
bei init_done = 0 ist fhem grundsätzlich in einem unfertigen und unbekannten zustand. unter anderem läuft die select loop noch nicht und man kann nicht auf mögliche probleme beim start reagieren. vor dem init_done fehlen definitiv alle attribute, readings und eventuell abhängige devices.

Achtung - $init_done ist nicht nur beim FHEM Start relevant.
$init_done wird auch zur Laufzeit von FHEM auf 0 gesetzt, wenn (und solange) ein RereadCfg durchgeführt wird.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

justme1968

ja. und da ist der zustand unter umständen noch viel unfertiger. nebenbei sind init_done = 0 beim start und init_done=0 beim RereadCfg nicht identisch.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

Wzut

Zitat von: justme1968 am 26 November 2020, 18:45:37
nebenbei sind init_done = 0 beim start und init_done=0 beim RereadCfg nicht identisch.
Gut zu wissen, ich leite daraus für mich ab : !$init_done bekommt in meinen Modulen statt der heutigen Bedeutung "noch nicht" ab sofort die neue "jetzt gerade nicht" 
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

dominik

Folgendes mein Grund warum ich es benötige:

FHEM erwartet, dass gewisse Funktionen / Initialisierungen innerhalb von Define ablaufen. Darunter fällt z.B. setDevAttrList(), das geht nur in Define, danach hat es keine Auswirkung. In meinem Fall benötigt das Define jedoch Zugriff auf den Prozess, der erst mit CoProcess gestartet wird.

Im konkreten Fall geht es um das PythonBinding (https://github.com/dominikkarall/fhem_pythonbinding). Alles was ich sonst in Perl im Define geschrieben habe, schreibe ich jetzt in Python in einem Python Define. Dieses Define kann ich nun aber nicht zum Startup aufrufen, da der CoProcess zuerst gestartet werden muss. Das bedeutet für mich aktuell, dass Python Module erst bei init_done=1 initialisiert werden und nicht davor.
Gerade zur Definition welche Attribute ein Device hat (das weiß nur der Python Code), kann ich daher nicht auf setDevAttrList() zugreifen und muss über userattr gehen. Natürlich ist das auch eine Möglichkeit, aber aus meiner Sicht nicht der schönste Weg, schon alleine deshalb, weil das Python Define nicht innerhalb von init_done=0 ausgeführt wird.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

justme1968

ohne genau nachgeschaut und nachgedacht zu haben sehe ich nicht warum setDevAttrList nicht auch nach dem define funktionieren sollte. von den beiden modulen die es scheinbar bisher verwendet wird es in einem aus der NotifyFn aufgerufen und ich würde vermuten das es dort funktioniert. was übersehe ich ?

falls setDevAttrList irgendwelche Einschränkungen bezüglich zeitpunkt hat sollte das meiner meinung nach ganz unabhängig von allem anderen behoben werden.

im übrigen wird jedes define das ein anwender interaktiv von hand eingibt bei init_done = 1 durchgeführt und ein modul muss auch damit klar kommen.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

rudolfkoenig

ZitatDarunter fällt z.B. setDevAttrList(), das geht nur in Define, danach hat es keine Auswirkung.
Das ist so nicht richtig: setDevAttrList hat selbstverstaendlich auch nach dem define eine Auswirkung.

Diese Funktion ermoeglicht instanzspezifische Attribute, und die Funktion im define aufzurufen ist natuerlich sinnvoll, da beim Einlesen von fhem.cfg die Attribute direkt nach dem define gesetzt werden. Den gleichen Effekt erreicht man mit dem (ebenfalls instanzspezifischen) userattr Attribut, das ist halt etwas weniger elegant, weil der Benutzer diese Liste sieht und anpassen kann. Eine weitere Alternative ist fuer die Zeit der Initialisierung mit setDevAttrList(".*) alles zu erlauben, und hoffen, dass die fhem.cfg Editierer sich nicht vertippen, und der CoProzess immer und schnell die richtige Liste meldet.

Auf der anderen Seite finde ich es unverantwortlich, einen Prozess zu starten, der FHEM blockiert, nur damit man keine Daten in FHEM speichern muss. In diesem Fall hat man auch keinen Support vom FHEM Framework, da dieser vom globalen select abhaengt, d.h. man darf die Finger schmutzig machen mit allen Details der Kommunikation.

justme1968

#10
ok. ich habe gerade den betreffenden thread gefunden. das problem ist nicht das setDevAttrList nicht später aufgerufen werden kann sondern das bevor es gesetzt ist die attribute eventuell nicht bekannt sind und nicht wieder hergestellt werden.

ich denke zuerst alles erlauben und später einschränken ist hier die richtige lösung.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

dominik

#11
Ok, sorry, ihr habt Recht, die Fehlersituation ergab sich aufgrund der nach dem Define nicht vorhandenen Attribute und somit wurden die in fhem.cfg gespeicherten Werte nach dem Start nicht übernommen.
Alle möglichen Attribute per Default setzen geht leider nicht, da auch diese Menge erst nach dem Start des Python Servers vorhanden ist.

ZitatEine weitere Alternative ist fuer die Zeit der Initialisierung mit setDevAttrList(".*) alles zu erlauben, und hoffen, dass die fhem.cfg Editierer sich nicht vertippen, und der CoProzess immer und schnell die richtige Liste meldet.
Ah, ich wusste nicht, dass man bei setDevAttrList auch Wildcards verwenden kann. Das wäre natürlich die Lösung! Danke!

ZitatAuf der anderen Seite finde ich es unverantwortlich, einen Prozess zu starten, der FHEM blockiert, nur damit man keine Daten in FHEM speichern muss. In diesem Fall hat man auch keinen Support vom FHEM Framework, da dieser vom globalen select abhaengt, d.h. man darf die Finger schmutzig machen mit allen Details der Kommunikation.
Was meinst du mit blockieren? Der CoProcess blockiert FHEM nicht, genau so wenig blockiert der Python Code FHEM. Ich musste nur einen Teil "blockierend" machen, nämlich die Funktionsaufrufe der Python DefineFn, AttrFn, usw. da die FHEM Funktionen im Standard auch direkt in der Perl FHEM Mainloop abgewickelt werden und somit "blockieren". Die Daten speicher ich bereits alle in FHEM, in Python werden diese nur zur Laufzeit verarbeitet.

//Edit: quote Tags korrigiert
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

betateilchen

kannst Du Deinen letzten Beitrag bitte lesbar gestalten? Danke.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

ZitatWas meinst du mit blockieren?
Da du geschrieben hast, das du den "vorzeitigen" CoProzess wegen setDevAttrList benoetigst, habe ich angenommen, dass im define der zweite Prozess gestartet werden soll, und solange gewartet (d.h. FHEM blockiert) wird, bis die Antwort vom zweiten Prozess eintrifft, und setDevAttrList mit dem richtigen Wert aufgerufen werden kann.

dominik

Das ist ein separates Modul welches den CoProcess startet. Aber du hast Recht, das CoProcess Modul (10_PythonBinding.pm) muss vor den eigentlichen Modulen (10_PythonModule.pm) initialisiert werden...und sogar dann kann es sein, dass der Start 2-3s dauert und es kurzzeitig zu einem Blocking kommt wenn der CoProcess noch nicht fertig gestartet hat.
Schön wären asynchrone FHEM Define, Attr, ... Funktionen :)

Also wenn setDevAttrList(".*") funktioniert, kann das Thema als erledigt betracht werden. Außerdem würde es, wie Rudi richtig festgestellt hat, trotzdem noch zum Blockieren kommen, da ich nicht garantieren kann, dass ein Modul 100% fertig geladen (CoProcess gestartet) ist bevor weitere Module initialisiert werden. Das ginge vermutlich nur mit async/await ohne blockieren.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik