1 Abbildung JavaSpaces in AID Thomas Ewender Freie Universität Berlin.
-
Upload
malger-strehl -
Category
Documents
-
view
104 -
download
0
Transcript of 1 Abbildung JavaSpaces in AID Thomas Ewender Freie Universität Berlin.
1
Abbildung JavaSpaces in AID
Thomas Ewender
Freie Universität Berlin
2
Inhalt
Erläuterung des Beispiels Kommunikation über verteilte Datenstruktur Verhalten der Umgebung Verhalten der Komponente
Aufrufbasierte Schnittstelle Abbildung in AID
IN-Ereignisse INOUT-Ereignisse Mögliche OUT-Ereignisse Initialisierung der Komponente
3
Auftragssystem
MP3WorkerMP3Worker
MP3RequesterMP3Requester
Ergebnis-tupelraum
Ergebnis abblegen
Auftrag ablegen
Auftrag annehmen
Auftrag ablegen
Ergebnis entgegennehmen
Auftrags-
tupelraum
4
Abbildung einer JavaSpaces-Komponente in AID (Treiberseite)
X
XYVermittlungs-
kanal
Fremdartige Umgebung
Vermittlungskanal
StellvertreterTreiber
JavaSpaces-Komponente
5
Beispiel für eine JavaSpaces-Komponente: Ein fairer MP3Worker Der MP3Requester legt Aufträge mit den für den
Umwandlungsprozess benötigten Daten (binäre WAV-Daten, Dateiname) in einem JavaSpace ab.
Ein oder mehrere MP3Worker nehmen diese in einem MP3Request-Objekt gekapselten binären WAV-Daten aus dem JavaSpace, wandeln diese in MP3-Daten um und legen das Ergebnis, gekapselt in einem MP3Result-Objekt, wieder im JavaSpace ab.
Betrachtete Komponente: Schnittstelle der MP3Worker
6
Beispiel für eine JavaSpaces-Komponente: Ein fairer MP3Worker
MP3Requester
MP3Worker
MP3Worker
MP3Worker
MP3Request
MP3Result
MP3Request
MP3Result
JavaSpace
Channel
MP3Request
MP3Result
7
Kommunikation über verteilte Datenstruktur Die verteilte Schlange wird in JavaSpaces durch zwei
Begrenzer-Objekte head und tail der Klasse Index realisiert. Sie beinhalten die Indizes für den Kopf und das Ende der Schlange.
Alle Aufträge (MP3Request-Objekte) besitzen ebenfalls eine Position innerhalb der Schlange
tail (Klasse Index)
12
1012 11 8 79
MP3Requests
7
head (Klasse Index)
8
Kommunikation über verteilte Datenstrukturpublic class Index implements Entry {
public String type; // "head" or "tail"public String channel;public Integer position;public Index() {}
public Index(String type, String channel, Integer position)
this.type = type;this.channel = channel;this.position = position;
}...
}
9
Erzeugen der Schlange im JavaSpacepublic class ChannelCreator {
...public static void main(String[] args) {
ChannelCreator c = new ChannelCreator();c.createChannel(args[0]);
}private void createChannel(String channelName) {
space = SpaceAccessor.getSpace();Index head =
new Index("head", channelName, new Integer(1));Index tail =
new Index("tail", channelName, new Integer(0));space.write(head, null, Lease.FOREVER);space.write(tail, null, Lease.FOREVER);
}}
10
Der faire MP3Requester
Der MP3Requester nimmt Rücksicht auf die Begrenzungsobjekte der verteilten Schlange
Dies geschieht in der Methode getRequestNumber, die die Handhabung des tail-Objekts übernimmt und die Position, unter der der Auftrag eingefügt werden muss, zurückliefert.
11
Der faire MP3Requester: Ablegen des Auftragsprivate Integer getRequestNumber(
String channel) {Index template =
new Index("tail", channel);Index tail = (Index)
space.take(template, null, Long.MAX_VALUE);
tail.position++;space.write(tail, null, Lease.FOREVER);return tail.position;
}
12
Der faire MP3Requester: Ablegen des Auftragsprivate void append(String channel, String
inputName, byte[] rawData, String from) {
Integer num = getRequestNumber(channel);MP3Request request =
new MP3Request(channel, num, inputName, rawData, from);
space.write(request, null, Lease.FOREVER);}
13
Der faire MP3Requester: Auslesen des Auftrags
public void getResults(String from) { MP3Result template = new MP3Result(from);MP3Result result = null;String outputName = "";
while(true) { result = (MP3Result)space.take(
template, null, Long.MAX_VALUE); displayResult(result);
}}
14
Der Konterpart: Der faire MP3Worker Die MP3Worker überprüfen ständig, ob Aufträge
im JavaSpace vorhanden sind.
while(true) {
processNextRequest();
}
15
Der Konterpart: Der faire MP3Workerprivate void processNextRequest() {
Index tail = readIndex("tail", channel);Index head = removeIndex("head“, channel);
if (tail.position.intValue() < head.position.intValue()) {
// there are no requestswriteIndex(head);return;
}
16
Der Konterpart: Der faire MP3Worker
// get the next request & increment the headMP3Request request = removeRequest(channel,
head.position);head.position++;writeIndex(head);
// encode mp3 using request object // data is stored in tmpOutputFile...outputData = Utils.getRawData(tmpOutputFile);MP3Result result = new MP3Result(inputName,
outputData, from);space.write(result, null, Lease.FOREVER);...
}
17
Schnittstelle der Komponente aus Sicht einer aufrufbasierten Java-Umgebungpublic interface MP3Worker {
//public MP3Worker(String channelName);
public int getTailPosition(String channel);
/** @Async **/public void setTail(String channel, int position);
public byte[] encodeMP3( String inputName,String channelName,int position,String from,byte[] data
);}
18
Abbildung in AID mit Hilfe von Annotationen: IN-Ereignisse
IN setTail
string channel,
int position
| classname_in=channel.Index
| attribute_in type=tail
| spacename_in=music.mp3ts
19
Erinnerung Klasse Indexpackage channel;public class Index implements Entry {
public String type; // "head" or "tail"public String channel;public Integer position;public Index() {}
public Index(String type, String channel, Integer position)
this.type = type;this.channel = channel;this.position = position;
}...
}
20
Abbildung in AID mit Hilfe von Annotationen: INOUT-EreignisseINOUT getTailPosition
string channel
RETURNS
int position
| classname_out=channel.Index
| attribute_out type=tail
| spacename_out=music.mp3ts
21
Abbildung in AID mit Hilfe von Annotationen: INOUT-Ereignisse Für die Entnahme des Tupels wird die
Belegung der Attribute gebraucht (hier channel). Information fließt in beide Richtungen.
Synchrones INOUT-Ereignis gewählt, da OUT-Ereignis von der Komponente initiativ ausgehen müsste und asynchron nur in eine Richtung geschickt würde.
22
Abbildung in AID mit Hilfe von Annotationen: INOUT-Ereignisse Unterscheidung der JavaSpaces-
Operationen take und read: Im Standardfall wird das Tupel aus dem
Tupelraum entnommen (take). Das ist im Beispiel der Fall.
Soll es nur gelesen werden, ist die Annotation read_only nötig.
23
Umsetzung von encodeMP3(…)
Umsetzung dieser Schnittstellenmethode:public byte[] encodeMP3(
String inputName,String channelName,int position,String from,byte[] data
); In JavaSpaces: Aufeinanderfolgendes Schreiben
und Entnehmen der Tupel MP3Request und MP3Result
24
Umsetzung von encodeMP3(…)MP3Request request =
new MP3Request(channel, num, inputName, rawData, from);
space.write(request, null, Lease.FOREVER);
...
MP3Result template = new MP3Result(from);
MP3Result result =
(MP3Result)space.take(
template, null, Long.MAX_VALUE);
25
Abbildung in AID mit Hilfe von Annotationen: INOUT-Ereignisse (Teil 2) Zusammenfassung der Ablage und
Entnahme semantisch zusammengehöriger Tupel zu einem einzigen AID-Ereignis
Abstraktion vom reinen Schreiben und Entnehmen von Tupeln hin zur Frage-Antwort-Semantik von AID
Nur syntaktische Erweiterung, lässt sich auch durch die bisher definierten Abbildungen beschreiben
26
Abbildung in AID mit Hilfe von Annotationen: INOUT-Ereignisse (Teil 2)INOUT encodeMP3
string channelName, | writeint position, | writestring inputName, | matching_parambyte[] data, | write string from | matching_param
RETURNSbyte[] data| classname_in mp3converter.MP3Request| classname_out mp3converter.MP3Result| spacename_in music.mp3ts| spacename_out music.mp3ts
27
Abbildung in AID mit Hilfe von Annotationen: INOUT-Ereignisse (Teil 2) Zuerst wird ein Entry-Objekt von Typ classname_in
(MP3Request) erzeugt und seine Attribute mit denjenigen Parametern gesetzt, die die Annotation write besitzen.
Konstante Attribute werden durch die Annotation attribute_in erkannt und die entsprechenden Felder des Entry-Objekts gesetzt.
Mit matching_param annotierte Parameter werden ebenfalls gesetzt
Dieses Objekt wird in den Tupelraum abgelegt.
28
Abbildung in AID mit Hilfe von Annotationen: INOUT-Ereignisse (Teil 2) Anschließend wird ein Template vom Typ
classname_out erzeugt, um ein Anwort-Tupel zu entnehmen.
Attribute des Template-Objekts werden die Werte der mit take und matching_param annotierten Parameter und der Annotationen attribute_out zugewiesen.
Mit dem Template wird eine take-Operation auf den JavaSpace ausgeführt und die Rückgabewerte des AID-Ereignisses entsprechend dem Ergebnistupel gesetzt.
29
Unterscheidung der INOUT-Ereignisse Zwei Arten von INOUT-Ereignissen sind zu
unterscheiden: Schreiben und Entnehmen von Tupel im Gegensatz zu lediglichem Entnehmen von Tupeln
Einführung einer Annotation wie retrieve_only um den Unterschied zu spezifizieren?
Alternative: Bei Fehlen der Annotation classname_in wird angenommen, dass kein Tupel abgelegt wird, sondern nur ein Tupel entnommen/gelesen wird
30
Mögliche OUT-Ereignisse im AID-Stil Ein OUT-Ereignis im AID-Stil müsste von der
Komponente initiativ ausgehen und asynchron in eine Richtung fließen
Eine Möglichkeit wäre die Verwendung von notify und EventListener, die in JavaSpaces angeboten werden
Der Treiber registriert sich für alle Tupel, die in OUT-Ereignissen beschrieben sind. Überlegung: welche Template-Objekte sollen verwendet werden?
Im Fall einer Benachrichtigung des Treibers wird diese Information an die Umgebung weitergeleitet
31
Mögliche OUT-Ereignisse im AID-Stilpublic interface JavaSpaces …{ …
EventRegistration notify(Entry tmpl,Transaction txn, RemoteEventListener listener, long lease,
MarshalledObject handback)
}
public interface RemoteEventListener … {
…
notify(RemoteEvent theEvent)
}
32
Initialisierung der Komponenten Möglichkeiten:
Aufruf eines Java-Programms Erzeugung eines Threads Erzeugung eines Objekts
Unterscheidung mit Hilfe der Annotation creation_mode, die die Werte process, thread oder instantiation annehmen kannn
33
Initialisierung der Komponenten: Möglichkeit 1: Prozesserzeugung Im Bsp.: Aufruf der main-Methode der Klasse
ChannelCreator, Konfiguration über die Kommandozeilenargumente
Annotationen für die für Jini notwendige Konfiguration: System-Properties (notwendig für Codebase, SecurityManager und Policy)
Annotationen für Pfad, Klassennamen, Standardoptionen (-jar, -classpath,…)
34
Initialisierung der Komponenten: Beispiel zu Möglichkeit 1INIT | classname = mp3converter.ChannelCreator
| creation_mode = process| path=/usr/home/mp3converter| property
java.security.policy=policy/policy.all| property java.lang.SecurityManager=
java.lang.SecurityManagerstring channelname, int init_size, string spacename
Resultiert in dem folgenden Aufruf:
java -Djava.security.policy=policy/policy.all-Djava.lang.SecurityManager=
java.lang.SecurityManagermp3converter.ChannelCreator channelname
init_size spacename
35
Initialisierung der Komponenten: Möglichkeit 2: Objekterzeugung Aufruf des Konstruktors einer Java-Klasse Dem neu zu erzeugenden Objekt werden
sämtliche zur Konfiguration notwendigen Parameter (u.a. Name des JavaSpace) über den Konstruktor übergeben.
Die hierfür notwendigen Annotationen beschränken sich auf die Angabe des Klassennamens
36
Offene Frage: Fehlerbehandlung Benutzerdefinierte Ausnahmen sind beim Austausch von
Tupeln via JavaSpaces nicht vorgesehen Für das Schreiben und Lesen von Entry-Objekten sind
nur Ausnahmen definiert, die sich auf den Kommunikationsvorgang an sich beziehen und nicht auf das Ereignis, das durch das Schreiben/Lesen des Entry-Objekts repräsentiert wird.
Letztendlich existiert also für JavaSpaces-Komponenten keine Möglichkeit, Ausnahmen im Sinne von AID zu signalisieren.
37
Offene Frage: Methodenaufruf auf TupelDie Wahrheit über die Klasse Index: Die
Inkrementierung findet über einen Methodenaufruf statt.
public class Index implements Entry { ...public void increment() {position = new Integer(position + 1);
}
}
38
Offene Frage: Methodenaufruf auf Tupel Mögliche Darstellung in AID:
INOUT getTail string channel
RETURNS Tail
INOUT setTail Tail
39
Offene Frage: Methodenaufruf auf Tupel Mit Hilfe des Interfaces Tail:
interface Tail
INOUT increment
INOUT getPosition RETURNS int pos
40
Methodenaufruf auf Tupel: Überlegungen Vermengung von tupelbasiertem und
aufrufbasiertem Interaktionsstil Mit dem Methodenaufruf sind auch
Zugriffsmethoden für die Klassenvariablen abzubilden (getter und setter)
Der Aufrufer wäre für das richtige Setzen der Klassenvariablen des Tupels selbst verantwortlich
41
Methodenaufruf auf Tupel: Überlegungen Mit der Möglichkeit, auf die Tupel als Objekte
zuzugreifen, lassen sich alle JavaSpaces-Komponenten mit den drei Operationen write, read, take und entsprechenden Interface-Definitionen für die Tupel (Entries) beschreiben
Methodenaufrufe auf Tupel sind im Grunde nicht notwendig, da alle Attribute der Tupel öffentlich sind und so beliebig veränderbar
42
Vielen Dank fürs Zuhören…!
43
Literatur
Eric Freeman, Susanne Hupfer, Ken Arnold: JavaSpaces Principles, Patterns, and Practice. 1999.
Sun Microsystems, Inc.: JS – JavaSpaces™ Service Specification, Version 2.2. http://www.jini.org/nonav/standards/porter/doc/specs/html/js-spec.html
Eric Freeman, Susanne Hupfer: Make room for JavaSpaces. http://www.javaworld.com/javaworld/jw-01-2000/jw-01-jiniology_p.html
Peter Löhr: Accommodating Heterogeneous Interaction Styles in Component-Based Software Architecture. 2005.
Peter Löhr: AID-Memo. 2005.
44
Anhang
45
Quellcode: MP3Request
public class MP3Request implements Entry {public String channelName; // recipient of requestpublic Integer position; // position # of request
// in channelpublic String inputName; // file pathpublic byte[] data; // content of the filepublic String from; // who sent the request
public MP3Request() { // the no-arg constructor } ...
}
46
Quellcode: MP3Result
public class MP3Result implements Entry {public String inputName;// name of file that was encodedpublic byte[] data; // raw MP3 data public String from; // who sent the request
public MP3Result() { // the no-arg constructor }…
}
47
JavaSpaces interface
Entry read(Entry tmpl, Transaction txn, long timeout)
Entry take(Entry tmpl, Transaction txn, long timeout)
Lease write(Entry entry, Transaction txn, long lease)
Entry readIfExists(Entry tmpl, Transaction txn, long timeout)
Entry takeIfExists(Entry tmpl, Transaction txn, long timeout)
EventRegistration notify(Entry tmpl, Transaction txn, RemoteEventListener listener,
long lease, MarshalledObject handback)