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