APL Application Server

Ausgangssituation

Es sind in APL geschriebene Anwendungsprogramme gegeben. Diese arbeiten bisher vollständig autark und besitzen keinerlei Netzwerkfähigkeiten. Die Programme bieten die Möglichkeit verschiedene Berechnungsfunktionen auszuführen, die jeweils in entsprechenden APL Funktionen vorliegen. Diese Funktionen müssen von Zeit zu Zeit angepasst und gewartet werden. Solche Anpassungen gehen bisher immer mit einem vollständigen Austausch des APL Programms und einem entsprechend aufwendigen Roll-Out einher.

Aufgabe

Die gegebenen Anwendungsprogramme sollen netzwerkfähig gemacht werden. Die wartungsintensiven Programmteile sollen ausgelagert und an einer zentralen Stelle zusammengefasst werden. Die autarken Programme werden damit zu Clients, welche die ausgelagerten Funktionen im Zusammenspiel mit einem Server verwenden.

Die bestehenden APL Workspaces sollen so weit es geht erhalten bleiben. Die darin vorhandenen Lösungen sind gut getestet und in der Praxis bewährt. Die Anwender sind mit der gegebenen Oberfläche vertraut. Daher ist eine von Grund auf beginnende Neuentwicklung der Applikationen zu vermeiden.

Lösungsvorschlag



Die grundlegende Idee besteht darin, den gesamten mit den vorhandenen APL Workspaces gegebenen Programmcode grundsätzlich beizubehalten. Es erfolgt lediglich eine Trennung in den Anwendungsbezogenen Teil (nachfolgend Client genannt) und den berechnungsbezogenen Teil (nachfolgend Modul genannt).



Auch nach dieser Aufteilung soll der Programmablauf im Client-Workspace wie gewohnt erhalten bleiben. Wann immer eine dem Modul-Workspace zugeordnete Funktion aufzurufen ist, geschieht dies über eine Kommunikation zwischen dem Client und dem Modul. Der Client fordert den Funktionsaufruf beim Modul an, welches die gewünschte Funktion ausführt und das Ergebnis an den Client zurückgibt.

Der Vorgang eines auf diese Weise ablaufenden Funktionsaufrufs wird als Run-At-Server bezeichnet, kurz RAS.

In der oben beschriebenen Kommunikation ist klar eine Client-Server Struktur zu erkennen. Die direkte Implementierung des Moduls selbst als Server ist aber aus mehreren Gründen nicht sinnvoll. So ist z.B. damit zu rechnen, dass die im Modul enthaltenen Funktionen sehr zeit- und resourcenaufwendige Berechnungen durchführen. Läuft der Server im gleichen Workspace parallel, so ist eine Beeinträchtigung der Antwortzeiten auf Anfragen anderer Clients nicht auszuschliessen. Des weiteren müssen alle für die Berechnung benötigten Daten in dem Modul-Workspace gehalten werden. Würden mehrere Clientanfragen im gleichen Workspace bearbeitet, so käme es schnell zu einem Speicherüberlauf, bzw. WS-Full Fehler.



Daher wird für die eigentliche Kommunikation zwischen Client und Modul ein eigenes Programm eingesetzt: der (Application-)Server.

Der Server nimmt die Anfragen der Clients entgegen und sorgt dafür, dass die gewünschten Funktionen jeweils in einem eigenen Modul-Workspace ausgeführt werden. Er kümmert sich weiterhin um die Verwaltung der laufenden Module und sorgt dafür, dass die bei ihm gemeldeten Ergebnisse der Module an den jeweils richtigen Client weitergeleitet werden.

Einen weiteren Vorteil der Trennung zwischen Server und Modul erkennt man, wenn man die in der Ausgangssituation beschriebene Tatsache berücksichtigt, dass nicht wie bisher stets betrachtet nur ein Anwendungsprogramm vorhanden ist. Bei der Trennung des Anwendungs- und Berechnungsbezogenen Teils der Programme entstehen automatisch verschiedene Client- und auch verschiedene Modultypen. Wäre der Server in den Modulen integriert, so müsste dieser beim Erzeugen jedes einzelnen Moduls mit implementiert werden.



Entfernt man sich von der oben zur Veranschaulichung nur mit einem einzelnen Client und einem einzelnen Modul dargestellten Abbildung, so erhält man für die Kommunikation mit mehreren Clients und Modulen folgenden Aufbau:

Realisierung

Um eines der gegebenen Anwendungsprogramme in einen funktionstüchtigen Client- und Modul-Workspace aufzuteilen, sind nur wenige Schritte notwendig.

Für die Erstellung des notwendigen Moduls steht als Grundlage ein fertiges Basis-Modul bereit. Es sind lediglich noch mit dem )copy Befehl alle Funktionen, die später über RAS serverseitig ausgeführt werden sollen, aus dem ursprünglichen Anwendungsprogramm in den Basis-Modul-Workspace zu übernehmen. Anschliessend wird ein Runtime-Workspace mit dem gewünschten Modulnamen, unter dem der Client das Modul später ansprechen kann, erzeugt.

Für die Umwandlung des vorhandenen Anwendungsprogramms in einen Client, der die gewünschten Funktionen serverseitig ausführen lässt, sind einige wenige zusätzliche Funktionen notwendig. Diese sind in den Ursprungs-Workspace zu laden. Anschliessend ist jeder Funktionsaufruf, der von der RAS-Funktionalität Gebrauch machen soll, durch die Methode RAS_Cover zu covern. Dazu wird dem Aufruf der RAS_Cover Befehl vorangestellt, der eigentliche Funktionsname in Hochkommata gesetzt und ggf. die Parameter geklammert. Beispiel:

Vorher
Nachher
RES2 Calc_1 3 RESRAS_Cover 2 'Calc_1' 3
RES2 3 Calc_2 3 (1 2) RESRAS_Cover (2 3) 'Calc_2' (3 (1 2))
RESCalc_3 2 3 RESRAS_Cover 'Calc_3' (2 3)

Bei Funktionen, die laufzeitabhängige globale Variablen benötigen, ist zusätzlich dafür zu sorgen, dass die gerade aktuellen Werte der Variablen mit an das Modul übergeben werden.
Auf diese Weise lässt sich Run-At-Server mit relativ geringem Aufwand in jedes vorhandene APL Programm einbinden.

Der Server selbst ist bei der Anpassung der gegebenen Anwendungsprogramme nicht betroffen. Dies bedeutet auf der einen Seite, dass das Einbinden der Run-At-Server Funktionalität sich tatsächlich auf den oben beschriebenen geringen Aufwand beschränkt. Ist der Server einmal fertig implementiert und als gegeben vorausgesetzt, entsteht bei der Umstellung weiterer APL Workspaces in diesem Bereich keinerlei zusätzlicher Aufwand.

Diese Trennung von den in der Ausgangssituation gegebenen APL Programmen eröffnet aber auf der anderen Seite auch die Möglichkeit für den Server eine vollkommen unabhängige Lösung zu wählen. Die intuitive Variante besteht sicherlich darin, für die Implementierung ebenfalls APL zu verwenden. Hierfür spricht in erster Linie die Fähigkeit APL Objekte wie Vektoren, Matrizen, genestete Strukturen usw. verarbeiten zu können. Solche Objekte können in beliebiger Ausprägung bei der Ausführung eines Moduls als Funktionsparameter vom Client übergeben werden. Umgekehrt ist das von einem Modul zurückgelieferte Ergebnis selbst ein APL Objekt.

Diese Tatsache beschränkt die Möglichkeiten der Serverrealisierung aber nur auf den ersten Blick auf APL. Denn die Objekte müssen zwar vom Client zum Modul sowie vom Modul zum Client weitergeleitet werden, Kenntnisse über den Inhalt oder die Struktur selbst sind aber für die Erfüllung der beschriebenen Anforderungen nicht notwendig. Das bedeutet, dass es aus Serversicht egal ist, ob APL Objekte oder einfache Zeichenketten weitergeleitet werden.

Unter Verwendung eines einfachen Konverters, der APL Objekte in Zeichenketten und diese wieder zurück in APL Objekte wandeln kann, hat man die Möglichkeit geschaffen den Server völlig unabhängig von APL implementieren zu können. Für die Realisierung des Konverters stehen geeignete Systemfunktionen in APL zur Verfügung. In Frage kommen z.B. die oder die Funktionen.



Entsprechend den beschriebenen Verfahren steht der für die praktische Realisierung der Run-At-Server Funktion benötigte Server in zwei Varianten zur Verfügung. Neben der klassischen in APL geschriebenen Variante kann auch eine Java Implementierung gewählt werden. Beide Varianten sind dabei untereinander beliebig austauschbar. Eine Anpassung der Client- und Modul-Workspaces an die jeweilige Serverimplementierung ist nicht notwendig.


Als Ansprechpartner stehen Ihnen Herr Denker und Herr Stolle von a.k.e zur Verfügung.