die Kurzfassung:
Da offenbar grade über größere Änderungen in der SW nachgedacht wird, plädiere ich dringend für:
- sicher ausgeführte Makroaufrufe (per Zuweisung / Ausführen bei Änderung), auch wenn diese parallel aufgerufen werden, denn da gehen welche reproduzierbar verloren!
- Möglichkeiten zur Parametrisierung von Makroaufrufen (insbesondere bei STARTE, evtl. auch bei AUFRUFEN)
- lokale Variablen, d.h. inhaltlich nur makrointern wirkend und damit überschreibfest für Parallelprozesse
- abwarten der kompletten durch INI ausgelösten Sequenz, bevor irgendwelche nachfolgenden "echten" Makros beginnen, abgearbeitet zu werden
--> ggf. generelles Überdenken der systeminternen Prozeß-Parallelität und -Verriegelung
Die Langfassung:
Nachdem ich der FHZ-Anlage und -SW nun eine ganze Reihe von Tests inkl. nun doch schon längerem Praxisbetrieb ausgesetzt habe, kristallisiert sich m.E. ein gravierendes grundlegendes Problem in der SW heraus, das vielleicht auch eine ganze Reihe der sonst hier diskutierten Bugs und Probleme verursacht.
Es handelt sich dabei um ein Laufzeitproblem bei der parallelen Abarbeitung interner Prozesse, für das man vielleicht auch ein gewisses Grundverständnis im Verhalten prozeßverarbeitender Software braucht, um dafür ein Gefühl zu entwickeln und sich da reindenken zu können. Ich hoffe ich bringe das nun trotzdem hier für den Normalanwender verständlich rüber, was ich meine. Und das paßt auch auf den ersten Blick nicht ganz zur Hobby-Anwendung mit dem eben mal aufgerufenen Makro. Aber auch der Hobby-Fernseher und das Hobby-Auto haben interne Prozesse zu beachten, die sie abzudecken sich vorgenommen haben ... aber vielleicht hat vorher auch wirklich noch niemand versucht, die hiesigen Makros funktional oder procedural, noch dazu massiv-parallel anzusprechen bzw. es wird nie jemand tun? Doch, zumindest ich habs versucht.
Praktisches Beispiel:
Da ich als Programmierer logischerweise faul bin (sonst wär ich ja keiner und würd nicht versuchen, dem Computer meine eigentliche Arbeit aufzuhalsen ), habe ich mir eine Reihe von m.E. nützlichen Funktionen geschaffen, die ich an der Stelle wo ich sie dann brauche nur noch aufrufen muß. Sagen wir mal, ich will eine Meldung ausgeben in ein ZEICHEN-Objekt, diese aber auch noch mit einem Zeitstempel versehen, in eine Log-Datei schreiben, je nach Priorität als Mail/SMS versenden usw.
Der Aufwand, all das zu tun, soll selbstverständlich an einer Stelle zusammengefaßt werden, denn 1. bin ich ja wie gesagt faul, und 2. will ich das Verhalten, wie denn nun Meldungen im System zu handhaben sind an einer zentralen Stelle pflegen und ggf. ändern können, und nicht jedesmal das ganze System nach "Funktionsbestandteilen" durchsuchen, die anzupassen sind. Pflegbare Software nennt man das. Also mußte eine Funktion her (da es hier nur sowas gibt: ein Makro), das genau das tut.
Da ich logischerweise aber jedesmal an der aufrufenden Stelle etwas anderes auszugeben habe, muß ich zumindest den auszugebenden Text (eigentlich auch die Priorität) als Parameter bei Aufruf mitgeben können.
Wie übergebe ich einem Makro ein Parameter? Logischerweise per Variable. FALSCH! Denn absehbare massiv-paralle Aufrufe verbieten das ja. Denn bei vielen im genau gleichen Moment erzeugten Meldungen weiß man ja nie, welche Meldung wirklich als nächste verarbeitet wird, also ob die vom Verarbeitungsmakroaufruf zeitlich getrennt gefüllten Variable nicht woandersher vor Verarbeitung schon wieder überschrieben wurde.
Beispiel für Parallelaufrufe: Eine ganze Gruppe von Objekten wird auf ein Event hin geschaltet, alle Objekte wollen beim Schalten eine Meldung loggen. Alle rufen das loggende Makro wiederum "bei Änderung" auf. Paralleler gehts kaum... Wer da nun gewinnt und vom System intern in welcher Reihenfolge bedient wird, entscheidet allein dieses nebst Kollege Zufall. Üblicherweise benutzt man deshalb dazu an den Aufruf gebundene Parameter (Objektmethoden, Funktionsparameter, z.B. sin(x) mit x=Parameter usw.)
Hmmmm... Aber leider bieten beide Makro-Aufruffunktionen (AUFRUFEN und STARTE) keine Möglichkeit zur unmittelbaren Parametrisierung(!!) Was einzig im Moment bleibt, ist offenbar folgender Weg
- Verarbeitungsobjekt ist selbst vom Typ ZEICHEN
- wird aufgerufen mit/durch direkte Parameterzuweisung in der Form
Code: Alles auswählen
verarbeitungsmakroobjekt:="Parameterstring" also z.B.
melde:="Bewegungsalarm Carport"
Nachteile:
Es gibt nur einen übergebbaren Parameter, zumindest ohne PHP-Funktionen zur Stringverarbeitung / -trennung zu bemühen (und wenn ich mir die Aufrufe so einiger eingebauter Funktionen ansehe... sind alle als Strings gequotet, sobald mehr als ein Parameter... Nachtigall, ick höre dir trapsen... )
Das ganze funktioniert zwar (erstmal / hier noch) ohne irgendwelche Abstürze oder Laufzeitfehler, aber leider eben NICHT parallel, da gehen Meldungen VERLOREN! Gegenbeweis: Warte-Befehle einbauen vor / nach den Aufrufen, schon kommen die fehlenden Meldungen, und das superstabil und reproduzierbar! --> Bug bei Abarbeitung parallel durchgeführter Zuweisung eines Objektes / Aufrufe gehen verloren / werden nicht ausgeführt!
Hmmmm... Warum gibt es eigentlich die Unterscheidung der beiden Makro-Startbefehle? Doch offenbar genau wegen der Parallelitätsprobleme! Logisch, parallele Prozeßverarbeitung ist ja auch nicht ganz simpel. Soll sich das System im FIFO-Prinzip doch selber drum kümmern, Klasse! Nur wie bekomm ich da nun bei Aufruf die Parameter mitgegeben??? Dringender Updatebedarf bzgl. Ergänzung um Parameter-Mitgabe bei Makroaufruf, oder Workaround mit lokalen / Session-Variablen, zumindest Session-ID-Mitgabe bei Aufruf o.ä.
Das war das einfache und m.E. für viele Forenleser nachvollziehbare Beispiel. Noch viel interessanter wirds natürlich, wenn man das oben gesagte z.B. auf größere Statistik-Berechnungsobjekte oder z.B. Datenbankarbeit anwendet, um dafür z.B. fertige und direkt aufrufbare Einzeiler-Funktionen zum Speichern oder Auslesen von Werten zu haben.
Ganz merkwürdige, aber m.E. ähnlich verursachte Effekte treten da aber bereits auf, wenn innerhalb des INI-Objektes einfach eine Funktion zum Aufbau des Datenbank-Providerstrings aus Projekt-System-Variablen und dessen Speicherung in einem ZEICHEN-Objekt aufgerufen wird. Bereits die nachfolgende Initialisierung der Objekte selbst und damit erstmals Datenbankarbeit in Benutzung des eben frisch gebauten Providerstrings führt dann dort zu Laufzeitproblemen des PHP-Blocks, aber nicht etwa im Code, sondern in den dort übergebenen Variablen(?!). Ursache ist eindeutig: Der Aufbau des Providerstrings im INI-Objekt war offenbar einfach noch nicht fertig. WARTE("00:00:02") eingefügt, und alles klappt (dort erstmal) bestens.
ABER: Das heißt ja andersherum, daß die ersten echten Makro-Verarbeitungen schon VOR Abschluß der INI-Objekt-Abarbeitung anlaufen????????!!!!
Wenn das wirklich so ist, sollte hier irgendwie ganz dringend und generell über die Parallelisierung von Prozessen, deren Verarbeitung, gegenseitiger Verriegelung sowie Parametrisierung nachgedacht werden, denn sonst KANN das PRINZIPIELL nie stabil laufen!
Ich weiß, das ist ein ganz schöner Hammer, aber ich denke mal, die Lösung ist es dicke Wert! Und vielleicht irre ich mich ja auch und denke einfach wieder mal nur zu kompliziert... Oder ist das genau einer der Gründe für das "größere Update"? ...dann warte ich gespannt!
Gruß Gerd
PS: In die gleiche Problematik fallen übrigens dann auch lokale Variablen. Wenn wir echte Parallelverarbeitung von Prozessen haben wollen, KÖNNEN funktional identische Arbeitsvariablen nicht mehr global gespeichert werden, da die sich ja dann auch gegenseitig überschreiben würden. Sie müßten hinsichtlich Existenz und Inhalt z.B. auf ihr "Heimatmakro" beschränkt bleiben und dürfen nur innerhalb eines Aufrufes inhaltlich wirken. Wennschon dennschon