Kontrollfluss in der TAA

Ein wesentliches Merkmal der TAA ist die Tatsache, dass Kontroll- und Datenfluss weitgehend voneinander entkoppelt sind. Der Datenfluss richtet sich nach den Datenbedarf der einzelne Bausteine, der erfüllt wird durch Zuweisungen aus anderen Bausteinen. Der Kontrollfluss beschäftigt sich mit der technischen Ausführung der Anwendungskomponenten, der Synchronisation zwischen den Bausteinen sowie mit der Bereitstellung aller notwendigen Umgebungsinformationen.

Prinzipiell kennt die TAA drei Arten von Kontrollfluss

  • synchron
  • asynchron
  • benutzerdefiniert

Welcher dieser Möglichkeiten für welche Aufgabe geeignet ist, entscheidet sich im Entwurf der Anwendung. Die technische Umsetzung der gewählten Methode wird durch die TAA realisiert, resp. durch die TAA unterstützt.

Bei den Bildern in den nachfolgenden Erläuterungen werden folgende Farben verwendet:

Die nachfolgende Erläuterungen sind bewusst keine technischen Anleitungen und Syntaxerklärungen, sondern sollen lediglich die logische Eigenschaften der Kontrollflussmöglichkeiten in der TAA erläutern. Genauere technische Details sind bspw. hier zu finden.

Synchron

Bei der synchronen Ausführung teilt ein Baustein der TAA mit, dass ein anderer Baustein ausgeführt werden soll, und dass der aufrufende Baustein warten möchte, bis der gerufene Baustein fertig ist. Je nach technischen Randbedingungen kann das bedeuten, dass der aufrufende Baustein weitermachen kann, sobald der gerufene Baustein bei der TAA seine Fertigstellung gemeldet hat, oder der aufrufende Baustein kann erst dann weitermachen, wenn der gerufene Baustein technisch abgeschlossen ist.

Im nachfolgenden Bild ist der Fall skizziert, in der die technische Umsetzung bspw. durch Implementierung beider Bausteine auf einer single-threaded Plattform erzwingt, dass der aufrufende Baustein warten muss, bis der gerufene Baustein technisch abgeschlossen ist.

Der Unregister des gerufenen Bausteins wird zwar wahrgenommen, dennoch muss der gerufene Baustein vollständig beendet sein, bevor der Aufrufer die Chance hat, technisch weiter zu arbeiten.

Anders sieht das aus, wenn die technische Umsetzung es erlaubt, dass beide Bausteine unabhängig voneinander ausgeführt werden können. Das zeigt das nachfolgende Bild. Darin ist zu sehen, dass zum Zeitpunkt des Unregister des gerufenen Bausteins der Aufrufer sofort weiter macht.

Einen derartigen Ablauf passiert bspw. wenn die beiden Bausteine in unterschiedlichen Prozessen oder unterschiedliche Threads laufen, oder gar auf unterschiedlichen Rechnern.

Yield

Es kann Situationen geben, in der ein gerufener Baustein zwar seine Fertigstellung dem Aufrufer mitteilen möchte, dennoch aber sich nicht technisch beenden möchte, sondern im Falle eines späteren Aufrufs in dem aktuellen Zustand verbeiben möchte, bspw. um teure Rüstzeiten nicht wiederholen zu müssen oder Oberflächenkonstrukte nicht erneut erstellen oder anzeigen zu müssen. In einem solchen Fall kann der gerufene Baustein anstelle eines Unregister eine Yield-Anweisung vornehmen. An dieser Stelle wartet der aufgerufene Baustein auf eine Wiederverwendung. Wenn der Aufrufer den gleichen Baustein erneut aufruft, wird die technische Ausführung des im Yield wartenden Bausteins fortgesetzt.

Wenn der Aufrufer selbst fertig ist und einen Unregister macht, wird der in Yield wartende Baustein davon unterrichtet und sollte seinerseits aufräumen und einen technischen Abschluss finden.

Bei der Nutzung von generierten Basis-Assemblies für die Implementierung des Bausteins kann das gleiche Verhalten erreicht werden. In diesem Fall wird jedoch standardmäßig der Baustein auch beim Unregister des Aufrufers erhalten bleiben, und der Cleanup erfolgt erst bei Prozess- oder Gevo-Ende. Somit kann der Baustein innerhalb des Gevos von unterschiedlichen Aufrufern wiederverwendet werden.

Die Yield-Funktionalität kann nur bei einem synchronen Aufruf verwendet werden. Bei den anderen Aufrufarten wird die Yield-Anweisung zur Beendigung des Bausteins führen.

Asynchron

Bei der asynchronen Ausführung (Spawn) teilt der Aufrufer der TAA mit, dass der auszuführende Baustein unabhängig vom Aufrufer aktiv sein soll, und der Aufrufer (zunächst) nicht auf Fertigstellung des Bausteins warten möchte. Die TAA trifft alle notwendigen Maßnahmen um dies zu ermöglichen. Dazu gehört unter anderem, dass sämtliche Daten, die laut Schnittstelle von dem asynchron auszuführenden Baustein verlangt werden, für diese kopiert werden, damit beide Bausteine auch in dieser Hinsicht voneinander unabhängig sind.

Am Ende des Gesamtablaufes, resp. am Ende des letzten Bausteins in einem Prozess, wird die TAA dennoch warten, bis all solche Bausteine fertig geworden sind.

Es besteht die Möglichkeit, dass der Aufrufer zu einem beliebigen Zeitpunkt an das Ergebnis des asynchron ausgeführten Bausteins Interesse hat. Das kann er durch eine WaitFor-Anweisung erreichen. Damit wird der Aufrufer an dieser Stelle warten, bis der aufgerufene Baustein per Unregister seine Fertigstellung gemeldet hat.

Wenn der aufgerufene Baustein fertig wird, und kein Aufrufer auf seine Fertigstellung wartet, wartet der gerufene Baustein solange im Unregister, bis sein Aufrufer das Ergebnis abholt.

Es ist jedoch auch möglich, dass der Aufrufer nie an einem Ergebnis interessiert war, und selbst bereits beendet ist. In dem Fall bedeutet der Unregister des gerufenen Bausteins keine Wartezeit. Am Ende des Prozesses jedoch, wird seitens der TAA auf Fertigstellung aller solchen asynchronen Bausteinen gewartet.

Man beachte, dass ein per Spawn gestarteter Baustein auch nach dem Ende seines Aufrufers noch weiter arbeiten darf und kann, da die dem Baustein zur Verfügung stehenden Daten nicht im Gültigkeitsbereichs des Aufrufers liegen (wie bspw. lokale Objekte die als Argument zugewiesen wurden) sondern für den Baustein eigenständig kopiert wurden. In allen anderen Kontrollfluss-Fällen muss ein aufgerufener Baustein bei der TAA abgemeldet sein oder werden, wenn der Aufrufer sich beendet, damit der Gültigkeitsbereich resp. Lebensdauer der Objektdaten nicht zu Konflikten führt.

Benutzerdefiniert

Bei der benutzerdefinierten Variante des Kontrollflusses übernimmt die TAA keine Aktivitäten zum Starten des zu rufenden Bausteins. Die TAA sorgt lediglich für eine Buchführung, bei der später erkannt werden kann, wozu ein Baustein, der sich per Register bei der TAA meldet, gehört, damit zu diesem Zeitpunkt die Umgebungsbedingungen für eine Ausführung im Rahmen der Aufrufbeziehung geschaffen werden können. Das konkrete Starten des Bausteins sowie alle Synchronisationen zwischen Aufrufer und Aufgerufenen obliegt der Verantwortung des Anwendungsentwicklers. Der Aufrufer muss lediglich ein sog. Token, welche er von der TAA durch die Prepare-Anweisung bekommt, dem Aufgerufenen mittteilen. Dieses Token muss beim Register des Aufgerufenen übergeben werden.

Wenn einmal bei der TAA ein Baustein als benutzerdefiniert aufgerufen registriert ist (per Prepare-Anweisung), kann von dieser Information beliebig oft Gebrauch gemacht werden. Der konkrete Baustein (oder vielleicht sogar unterschiedliche Implementierungen dessen) kann immer wieder bei der TAA durch Register aktiv werden und sich wieder mit Unregister abmelden.

Wenn ein Baustein, der zu rufende Bausteine bei der TAA auf diese Weise gemeldet hat, selbst am Ende ist und einen Unregister macht, so werden alle derzeit noch aktive, also bei der TAA per Register gemeldete Bausteine über diese Tatsache per Event unterrichtet, und sollten als Reaktion darauf ihre Arbeit abschließen. Für Bausteine die trotzdem nach dieser Unterrichtung noch aktiv sind wird eine dementsprechende Fehlermedlung produziert.

controlflow · Zuletzt geändert: 18.04.2016 10:37

Copyright © 1992-2024 TeamWiSE Gesellschaft für Softwaretechnik mbH         Adressen |  Kontakt |  AGB |  Datenschutzerklärung |  Impressum