Updatewunsch: Sicherer Makroaufruf, Parametrisierung

Bugreports und Updatewünsche an die Firma contronics
Keine allgemeinen Fragen!

Moderator: Co-Administratoren

Antworten
gwanjek
Beiträge: 76
Registriert: 18.12.2006, 17:32
Wohnort: Ostseeküste

Updatewunsch: Sicherer Makroaufruf, Parametrisierung

Beitrag von gwanjek » 03.01.2007, 00:58

Hallo,
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 :D ), 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"
- dieses wiederum beginnt die interne Verarbeitung "bei Änderung" im objektinternen Makro

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... :D)

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! 8)

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 :-)

buempi
Ehrenmitglied
Beiträge: 12194
Registriert: 29.07.2006, 15:58
Wohnort: Schweiz
Danksagung erhalten: 5 Mal

Beitrag von buempi » 03.01.2007, 09:56

Auch ich denke, dass das ganze Konzept des Makro-Aufrufes bzw. der -Abarbeitung überdacht werden sollte.

Neben der fehlenden Möglichkeit, Parameter zu übergeben und der Tatsache, dass die Reihenfolge der Ausführung mehr oder weniger dem Zufall überlassen ist, kommt es aber auch regelmässig vor, dass Makros "bei Eingabe" und "bei Empfang" einfach nicht ausgeführt werden. Das ist nachweislich der Fall. Ob auch Makros ausfallen, die in einem bestimmten Zeitintervall ablaufen sollen und solche, die von anderen aufgerufen werden, habe ich bisher nicht festgestellt.

Zunächst aber ein Problem, das ich schon früher mal gepostet habe und das wohl ebenfalls mit der "Ablauf-Logik" zusammenhängt:


1. Uhrzeitvergleich im *INIT-Makro funktioniert nicht:

Ich habe ein Objekt Namens "Sollwert" vom Typ Zahl mit Startwert 20,00

Im *INIT - Makro steht folgendes:

wenn Uhrzeit>"06:00:00" dann
Sollwert:=22,50
endewenn
wenn Uhrzeit>"21:00:00" dann
Sollwert:=21,50
endewenn

Wenn ich HomeputerStudio (Rel. 60912) z.B. um 13.30 starte und daraufhin auch meine Anwendung, zeigt "Sollwert" 20,00 an.

Beendige ich die Anwendung und starte sie erneut (ohne HomeputerStudio zu beenden), wird der Wert richtig mit 22,50 angezeigt. Das lässt sich unzählige Male reproduzieren. Beim ersten Start falsch; bei den folgenden richtig.


2. Makro "bei Eingabe" wird nicht ausgeführt:

Ich habe einen virtuellen Taster. Das "bei Eingabe" hinterlegte Makro soll gewisse statistische Anzeigen am Bildschirm auf Null stellen. Es kommt regelmässig vor, dass ich auf diesen Taster klicke und die Farbe zwar wechselt, die Nullstellungen aber nicht erfolgen. Beim zweiten Klick funktioniert es dann.

Meine ziemlich komplexe Anwendung läuft auf einem älteren, langsamen Notebook. Bis vor kurzem habe ich den Fehler auf diese Tatsache zurückgeführt, weil sich der Fehler bei Versuchen auf meinem schnellen Arbeitscomputer nicht reproduzieren liess.

Dort war aber bei diesen Versuchen jeweils keine Schnittstelle angeschlossen; heute habe ich den Verdacht, dass vielleicht nur deshalb keine Aussetzer festgestellt werden konnten.


3. Makros "bei Empfang" werden nicht ausgeführt:

Seit einigen Monaten (Release 60912, ev. sogar schon früher) habe ich verdächtig viele Ausfälle meiner HMS-Sensoren festgestellt. Verzweifelt habe ich mal die Sensoren, mal die Schnittstelle umplatziert; alles ohne Erfolg.

Um zu überwachen, ob die Sensoren wirklich regelmässig empfangen werden, wird als erster Befehl im Makro des Sensors (Ausführung bei Empfang) einer Zeitvariable die aktuelle Zeit zugewiesen (die interne Variable *.CT kann dazu nicht verwendet werden, weil sie sich ja nur ändert, wenn die Temperatur seit der letzten Sendung geändert hat). Ich kenne den zeitlichen Abstand, in dem sich die HMS-Sensoren melden. Ein jede Sekunde ablaufendes Makro vergleicht nun diese Zeitspanne mit der Stoppzeit der Zeitvariablen. Bei Überschreitung einer gewissen Toleranz wird ein Sensor-Ausfall protokolliert und gleichzeitig die Ausfallstatistik am Bildschirm um 1 erhöht.

Vor kurzer Zeit ist mir nun aufgefallen, dass sich die Temperatur-Anzeige eines Sensors veränderte, kurz darauf aber der Ausfall-Zähler des betreffenden Sensors um 1 erhöht wurde. Ich traute meinen Augen nicht und setzte mich nun "jede freie Minute" vor den Bildschirm. Siehe da: Das Spiel wiederholte sich!

Ich wollte Gewissheit haben und baute in mein sekündlich ablaufendes Ausfall-Makro eine Routine ein, welche die *.CT - Variable mit meiner Zeitvariablen vergleicht. Ist die *.CT-Variable um mehr als eine Minute (!) grösser als meine Zeitvariable, wird ein Makroausfall protokolliert. Das passiert nun täglich 5 bis 10 mal. Dabei ist zu bedenken, dass die *.CT-Variable ja nur aktualisiert wird, wenn sich der Zustand (Temperatur) geändert hat. Raumtemperaturen bleiben aber oft über längere Zeit gleich, so dass zu diesen 5 bis 10 Ausfällen noch eine erhebliche Dunkelziffer hinzuzurechnen ist.

Auch hier glaubte ich, dass vielleicht mein langsamer Rechner verantwortlich ist. Über die Feiertage liess ich die Anwendung deshalb auf meinem Arbeits-PC (1,7 GHz) laufen. Das Ergebnis: Ich habe den Eindruck, dass hier die Zahl der nicht ausgeführten Makros sogar eher höher ist als auf dem langsamen Rechner....

Meine Anwendung ist ziemlich komplex, mit mehreren Makros, die im 1- bis 5-Sekunden-Rhythmus ausgeführt werden. Ist vielleicht die Ausführungswarteschlange einfach zu kurz, so dass sie bei bestimmten Konstellationen keine zusätzlichen Einträge mehr annimmt? Und gilt das dann auch für Makros, die im Zeitintervall ablaufen sollen oder von anderen Makros aufgerufen/gestartet werden?

3. Timeout Makro XY

Vor schätzungsweise etwa einem Jahr wurde ein neues Feature in die Homputer-Software eingebaut: Um Loops in einem Makro zu übersteuern, werden Makros, die länger als eine gewisse Zeit (wie lange?) "an der Arbeit" sind, abgebrochen. Es ertönt ein kurzes Warnsignal und in der Statuszeile wird während ganz kurzer Zeit die Meldung "Timeout Makro XY" angezeigt. Diese Meldung wird aber nicht einmal im MSFILE.TXT protokolliert. Fast jedes Mal, wenn ich nun die Zeit meines Notebooks mit der Netzwerk-Zeit synchronisiere, erfolgt so ein Abbruch, denn die Uhr des Notebooks geht etwas nach.

Dieses "Feature" sollte in den allgemeinen Einstellungen abgeschaltet werden können. Jeder ist selber für Loops verantwortlich, wenn er die Übersicht wegen zu vieler "GEHEZU" verloren hat. Mir ist einfach nicht wohl bei der Tatsache, dass ein wichtiges Makro mittendrin abgebrochen werden könnte, nur weil der Computer einen "Hänger" hat, weil z.B. Windows im Hintergrund wieder mal Selbstbefriedigung betreibt. Wenn in einem Ablauf nur die Hälfte der Zustände geschaltet und die Hälfte der Variablen verändert wird, läuft das System nachher ins Ungewisse. Oder werden Variablen und Schaltungen bei einem Timeout-Abbruch wenigstens auf den Ursprungswert beim Start des abgebrochenen Makros zurückgesetzt?


Nachträglich noch ein gutes und erfolgreiches 2007 an alle!

Viele Grüsse

Bümpi

contronics-RK
Beiträge: 954
Registriert: 18.07.2006, 15:58

Beitrag von contronics-RK » 08.01.2007, 18:47

Grundsätzlich ist das Konzept sehr gut durchdacht und auch sicher aufgebaut. Da werden wir in der geplanten Überarbeitung sicherlich nichts ändern.
Einiges Grundsätzliches zum besseren Verständniss:

Es gibt tatsächlich keine "Parallelverarbeitung". Die Makroanweisungen werden in einen optimierten Ausführungscode übersetzt, die Ausführungszeit eines Makros liegt normalerweise im Mikrosekunden-Bereich, wenn Anweisungen zur Dateiverabeitung oder PHP-Scripts enthalten sind können es einige Millisekunden werden.
Letztlich sind die Ausführungszeiten so kurz, dass es keine merklichen Verzögerungen bei der Ausführung gibt (es sieht tatsächlich so aus als würden die Makros gleichzeitig ausgeführt) - was länger dauert ist die Hardware-Kommunikation - diese läuft aber in einem separaten Thread.
Grundsätzlich ist es so, dass immer nur ein Makro gleichzeitig ausgeführt wird. Durch Start, Änderung bei Ausführung/Empfang aktivierte Makros werden über eine Ausführungswarteschlange nach dem FIFO-Prinzip gesteuert.
Während der Ausführung eines Makros können an anderer Stelle keine Werte geändert werden (weder durch Hardware noch durch andere Makros). Wenn man dass zulassen würde würde es vollkommen durcheinander gehen, weil ja in den Makros Programmabläufe in Abhängigkeit von Werten stattfinden. Wertänderungen während der Abarbeitung der Teilprozesse (Makros) würden zu absolutem Chaos führen. Einzige Ausnahme: Durch eine Warte-Anweisung wird das Makro unterbrochen, andere Makros werden ausgeführt und Hardware-Inputs werden aktualsiert - während dieser Unterbrechung können Werte natürlich von anderen Makros/Hardware verändert werden (das muss so sein).
Was zu Problemen führen kann:
Die unsachgemässe Verwendung der Option "Ausführung bei Änderung". Wenn diese Option falsch verwendet wird (z.B. aktiviert wenn der Objektwert im Makro verändert wird) kann es zu einer Art Endlosschleife kommen, die zu einem Überlauf der Ausführungswarteschlange führt (das wird in der Fehlerzeile angezeigt. Damit kann dann nichts mehr richtig funktionieren, weil die Ausführungswarteschlange für andere Aktionen blockiert ist (das war z.B. in einem der Programme, die wir jetzt mit Problemen im Zusammenhang mit dem Update bekommen haben der Fall).
Was noch passieren kann:
Wenn PHP-Funktionen im Hintergrund ausgeführt werden, ist es möglich, dass es hier zu Überschneidungen kommt. Wie anscheinend in einem hier geschilderten Fall wo eine PHP-Iniitalisierung im INIT-Makro durchgeführt wird. Da wir den PHP-Interprter nicht beeiflussen können (und wollen), können wir da nichts machen. Als workarround wäre es z.B. möglich Zeitschleifen mit PHP zu bauen - sicherlich keine tolle Lösung. Grundsätzlich ist es aber so: Das INIT-Makro wird als erstes ausgeführt, erst wenn das beendet wird (oder durch WARTE unterbrochen) werden andere Makros ausgeführt.

In der überarbeiteten Version sind Parameter für Makros geplant, da es übersichtlicher und einfacher ist als Variablen zur Parameterübergabe zu verwenden. Grundsätzlich ist es aber auch jetzt schon möglich Variablen zur Parameterübergabe zu nutzen: Variablen setzen, dann Makro mit der Anweisung AUFRUFEN ausführen lassen. In diesem Fall möglichst nicht STARTE verwenden, da man nicht weiss ob in der Ausführungswarteschlange nicht noch andere Makros stehe, die eventuell auch die Variablenwerte verwenden.

Ich hoffe es ist verständlich beschrieben und jetzt etwas klarer wie die Steuerung prinzipell funktioniert.

Freundliche Grüsse
contronics - Ralph Krapoth

Antworten

Zurück zu „homeputer Studio / Standard: Bugs & Updatewünsche“