• Keine Ergebnisse gefunden

5. Benutzeragent und ConTract Engine

5.5 Direkte und indirekte Kommunikation

Der Benutzeragent erwartet also die Aufgabe in Form einer Folge von Dateien. Da die Infor-mation möglicherweise zunächst nicht in dieser Form vorliegt, werden für jeden Auftragstyp Konverter benötigt, die die Information in Dateisequenzen umsetzen. Hier bieten sich zwei prinzipielle Möglichkeiten an:

• Die Umsetzung geschieht durch selbständige Programme („Stubs“), die für die ConTract Engine einen konkreten Service anbieten und die ihrerseits wieder den Benutzeragenten aufrufen (indirekte Kommunikation).

• Der Benutzeragent bietet die verschiedenen benötigten Schnittstellen an und wandelt die erhaltenen Informationen intern um (direkte Kommunikation).

5.5.1 Indirekte Kommunikation

Der Benutzeragent erwartet bei dieser Alternative nur die in standardisierte Form überführten Aufträge und bietet aus diesem Grunde nur eine einheitliche Schnittstelle an (siehe die Schnitt-stellen im Anhang):

void service (

in APRICOTS_Definitions::ConTractInstanceID ciid,

in APRICOTS_Definitions::StepInstance stepInstance, in APRICOTS_Definitions::EntryInvariant entryInvariant, in Transactions::Control control,

in string request, in APRICOTS_Definitions::FileSequence files) raises(APRICOTS_Definitions::Reject);

Der Benutzeragent wird dadurch unabhängig von den konkreten Aufträgen an den Benutzer.

Es ist somit möglich, auch ohne ein Umschreiben des Agenten Aufgabentypen entgegenzu-nehmen und zu verarbeiten, die zum Übersetzungszeitpunkt noch nicht bekannt waren. Eine Erweiterung des Aufgabenspektrums erfordert somit lediglich die Implementierung eines auf die neue Aufgabe zugeschnittenen Stubs; eine Veränderung des Benutzeragenten selbst wird nicht notwendig.

Die Schnittstelle, die ein solcher Stub der ConTract Engine anbietet, sollte dann in etwa so aussehen:

interface APRICOTS_SpecificService : APRICOTS_AsyncStepserver { void NameOfSpecificService(

in APRICOTS_StorageAgent::ObjectString conTractEngine, in APRICOTS_StorageAgent::StepInstance stepInstance, in string entryInvariant, in string exitInvariant, // ... Informationen, mit deren Hilfe sich eine Sequenz // von Dateien konstruieren läßt ... )

raises(APRICOTS_Stepserver::Reject);

Aus den wie auch immer gearteten Informationen, die der Stub erhält, konstruiert er eine Da-teisequenz, die er dann zusammen mit den ersten vier Parametern (conTractEngine, stepInstance, entryInvariant und exitInvariant) an den eigentlichen Benut-zeragenten weiterreicht.

Es ist jedoch nicht unbedingt notwendig, daß der Stub beim Aufruf durch die ConTract Engine alle Informationen erhält, die er für die Dateifolge benötigt. Denkbar wäre hier auch, die für die Aufgabe benötigten Informationen beim Storage Agent abzulegen und sie vom Stub dort abho-len zu lassen.

ConTract Engine Konkreter

Service A

bedeutet „ruft auf“

Konkreter Service C Konkreter

Service B

Benutzer-agent Storage

Agent

OTS Tasklist

Interface

generische Schnittstelle

Abbildung 26: Verwendung von Stubs mit direkter Antwort

Wenn der Benutzer eine Aufgabe bearbeitet hat und das Ergebnis durch das Tasklist Interface an den Benutzeragenten übermittelt worden ist, muß dieses Resultat an die zuständige Con-Tract Engine weitergereicht werden. Diese erwartet die Parameter in der im Skript festgelegten Reihenfolge. Für den Benutzeragenten besteht eine bearbeitete Aufgabe - genauso wie eine unbearbeitete - jedoch stets aus einer Sequenz von Dateien. Diese einfach an die Engine zu schicken, hätte zur Folge, daß im Skript jeder Aufruf eines Benutzeragenten mit einem Rück-gabewert, nämlich einer Dateifolge, notiert werden müßte. Ein etwas besserer Ansatz besteht darin, den Benutzeragenten die Dateisequenz zerlegen zu lassen und die Dateien jeweils als einzelne Parameter zu übergeben.

Am flexibelsten läßt sich die Rückgabe des Ergebnisses jedoch behandeln, wenn der Stub, der die Dateisequenz für einen bestimmten Aufgabentyp zusammengestellt hat, diese auch wieder

zerlegt. Er könnte das Resultat auch in anderer Form als Dateien an die ConTract Engine übermitteln; da diese Form aufgabentypspezifisch ist, ist eine Konvertierung der Dateifolge ohne die Mithilfe des jeweiligen Stubs durch den Benutzeragent nicht möglich. Als geringen zusätzlichen Aufwand muß sich der Benutzeragent bei dieser Variante die Adresse des zustän-digen Stubs merken, was bei einer direkten Antwort nicht notwendig ist.

ConTract Engine Konkreter

Service A

bedeutet „ruft auf“

Konkreter Service C Konkreter

Service B

Benutzer-agent Storage

Agent

OTS Tasklist

Interface

generische Schnittstelle

Abbildung 27: Verwendung von Stubs mit indirekter Antwort

5.5.2 Direkte Kommunikation

Die Alternative zur indirekten Kommunikation zwischen Benutzeragent und Tasklist Interface besteht darin, die aufgabenspezifischen Stubs in den Benutzeragenten selbst zu integrieren.

Durch diesen Ansatz gibt es nicht für jeden Aufgabentyp ein eigenes CORBA-Objekt, das wie-derum den Benutzeragenten aufruft; die zusätzlichen Einträge ins Implementation Repository entfallen. Die Anzahl der Aufrufe über das Netz wird bei dieser Alternative halbiert. Wo vorher jeweils zwei Netzzugriffe notwendig waren - nämlich der Aufruf des Stubs durch die ConTract Engine und des Benutzeragenten durch den Stub - wird jetzt nur noch einer benötigt.

Ein Nachteil bei diesem Vorgehen besteht in der erhöhten Komplexität des Benutzeragenten.

Bei der indirekten Kommunikation muß der Agent nichts über die einzelnen Aufgaben wissen

eine spezifische Methode anbieten muß. Wenn eine neue Art von Aufgaben hinzukommt, muß er entsprechend erweitert werden.

ConTract

Engine bedeutet „ruft auf“

Benutzer-agent Storage

Agent

OTS Tasklist

Interface

Konkreter Service A Konkreter

Service A

Konkreter Service A

Abbildung 28: Direkte Kommunikation zwischen Benutzeragent und ConTract Engine Ein weiteres Manko ist der durch die Zusammenfassung des Benutzeragenten und der einzel-nen Stubs und der dadurch erreichten Einsparung beim Kommunikationsaufwand erkaufte Verlust an Flexibilität. Durch die Trennung von Agent und Stubs in separate CORBA-Objekte wird es nämlich möglich, diese unabhängig voneinander zu implementieren; insbesondere die Wahl der Programmiersprache für die Implementierung der Stubs läßt sich unabhängig von der Realisierung des Benutzeragenten treffen. Außerdem halten sich die Einsparungen bei der Kommunikation in Grenzen, da ein Aufruf des Benutzeragenten durch die ConTract Engine -verglichen beispielsweise mit dem Zugriff auf den Storage Agent - nur relativ selten erfolgt.

Aus diesen Gründen erscheint die Aufteilung des Benutzeragenten in einen Hauptteil mit einer allgemeinen Service-Schnittstelle und aufgabenspezifische Stubs sinnvoller als die Integra-tion dieser Komponenten.