Verteilte Systeme
Verteilte System SS2017
Verteilte System SS2017
License: MIT License
Verteilte System SS2017
should send datagrams with multicast
https://docs.oracle.com/javase/tutorial/networking/datagrams/broadcasting.html
Die Textzeilen werden vom Server durchnummeriert (beginnend bei 1) und stellen eine eindeutige ID für jede Textzeile dar. Ein Redakteur-Client hat sich beim Server vor dem Versenden einer Textzeile diese Nummer zu besorgen und in der Zustellung seiner Nachricht an den Server diese Nummer der Textzeile voranzustellen.
Da die dem Server zugestellten Textzeilen bzgl. der Nummerierung in zusammenhängender Reihenfolge erscheinen sollen und Nachrichten mit Textzeilen verloren gehen können bzw. in nicht sortierter Reihenfolge eintreffen können, arbeitet der Server intern mit einer Deliveryqueue (DLQ) und einer Holdbackqueue (HBQ).
In der Deliveryqueue stehen die Nachrichten, die an Clients ausgeliefert werden können, maximal *** viele Textzeilen. Dies wird durch die Größe der Deliveryqueue vorgegeben.
In der Holdbackqueue stehen alle Textzeilen, die nicht ausgeliefert werden dürfen.
Der Server fügt einer empfangenen Nachricht der Zeichenkette jeweils die Empfangszeit beim Eintrag in die Holdbackqueue und die Übertragungszeit beim Eintrag in die Deliveryqueue hinten/rechts mittels werkzeug:timeMilliSecond() an. Zudem fügt er dieser Nachrichten-Liste diese Zeitstempel mittels erlang:now() am Ende hinzu.
Ein Leser-Client bekommt auf Anfrage gemäß Nachrichtennummerierung eine noch nicht an ihn ausgelieferte und beim Server bekannte Textzeile geliefert. In einem Flag wird ihm mitgeteilt, ob es noch weitere, für ihn unbekante Nachrichten gibt. Zudem wird ihm explizit die Nummer dieser Nachricht übermittelt. Wenn der Leser-Client nach neuen Nachrichten beim Server anfragt, dort jedoch keine neuen bzw. überhaupt noch keine Nachrichten vorhanden sind, sendet der Server eine nicht leere dummy-Nachricht.
Ein Leser-Client, der seit ** Sekunden keine Abfrage mehr gemacht hat, wird beim Server vergessen. Bei einer erneuten Abfrage (nach dem Vergessen) wird er wie ein unbekannter Leser-Client behandelt.
Wenn in der Holdbackqueue von der Anzahl her mehr als 2/3-tel an echten Nachrichten enthalten sind, als durch die vorgegebene maximale Anzahl an Nachrichten in der Deliveryqueue stehen können, dann wird, sofern eine Lücke besteht, diese Lücke zwischen Deliveryqueue und Holdbackqueue mit genau einer Fehlernachricht geschlossen, etwa: ***Fehlernachricht fuer Nachrichtennummern 11 bis 17 um 16.05 18:01:30,580|. Es werden keine weiteren Lücken innerhalb der Holdbackqueue behandelt! In dem Sinne wird die Holdbackqueue in diesem Fall nicht zwingend geleert. Die Fehlernachrciht ist nur durch eine entsprechende Zeichenkette in der Nachricht zu erkennen. Ansonsten hat sie das Format einer ganz normalen Nachricht, d.h. das System kann eine Fehlernachricht nach Speicherung in der DLQ nicht mehr als solche erkennen!
Der Server terminiert sich, wenn die Differenz von aktueller Systemzeit und Zeit der letzten Abfrage eines Clients länger als seine Wartezeit beträgt, d.h. seine Wartezeit wird durch Abfragen der Clients erneut gestartet bzw. bestimmt die maximale Zeit, die der Server ungenutzt läuft.
Der Server verwendet drei ADTs: HBQ (Datei hbq.erl), DLQ (Datei dlq.erl) und CMEM (Datei cmem.erl) als Gedächtnis für die Leser-Clients. Diese dürfen hauptsächlich nur als Erlang-Liste ([ ]) realisiert werden! Als Hilfsstrukturen dürfen Tupel eingesetzt werden. Dazu sind die weiter unten aufgeführten Vorgaben zu beachten!
Die HBQ ist als entfernte ADT zu implementieren. Ihre Schnittstelle ist daher durch Nachrichtenformate beschrieben. Die DLQ oder das CMEM sind als lokale ADT zu implementieren. Daher sind deren Schnittstellen durch Funktionen beschrieben. Intern kann die DLQ bzw. das CMEM jedoch als externer Prozess realisiert werden!
Der Server ist in Erlang/OTP zu implementieren und muss auf jedem Rechner im Labor startbar sein! Bei der Verwendung von Eclipse kann das problematisch sein. Die steuernden Werte sind in einer Datei server.cfg anzugeben. Der Server ist unter einem Namen im lokalen Namensdienst von Erlang zu registrieren (register(,ServerPid)).
m Folgenden wird die Schnittstelle des Servers für einen Client beschrieben.
/* Abfragen einer Nachricht */
Server ! {self(), getmessages}
receive {reply,[NNr,Msg,TSclientout,TShbqin,TSdlqin,TSdlqout],Terminated}
Beispiel: Server ! {<7016.50.0>, getmessages}
receive {reply,[15, "0-pclient@KI-VS-<0.64.0>-KLC: 15te_Nachricht. C Out: 29.04 08:43:24,871| HBQ In: 29.04 08:43:24,879| DLQ Out: 29.04 08:43:35,551| ", {1430,289804,872001}, {1430,289804,880000}, {1430,289804,880003}, {1430,289815,551001}],true}
/* Senden einer Nachricht */
Server ! {dropmessage,[INNr,Msg,TSclientout]},
Beispiel: Server ! {dropmessage,[93, "0-pclient@KI-VS-<0.64.0>-KLC: 93te_Nachricht. C Out: 29.04 08:43:38,569|", {1430,289818,569001}]}
/* Abfragen der eindeutigen Nachrichtennummer */
Server ! {self(),getmsgid}
receive {nid, Number}
Beispiel: Server ! {<7016.50.0>, getmsgid}
receive {nid, 42}
getmessages: Fragt beim Server eine aktuelle Textzeile ab. self() stellt die Rückrufadresse des Leser-Clients dar. Als Rückgabewert erhält er eine für ihn aktuelle Textzeile (Zeichenkette) zugestellt (Msg) und deren eindeutige Nummer (NNr). Zudem erhält er die Zeitstempel explizit (erstellt durch erlang:now(),TSclientout,TShbqin,TSdlqin,TSdlqout).Mit der Variablen Terminated signailiert der Server, ob noch für ihn aktuelle Nachrichten vorhanden sind. Terminated == false bedeutet, es gibt noch weitere aktuelle Nachrichten, Terminated == true bedeutet, dass es keine aktuellen Nachrichten mehr gibt, d.h. weitere Aufrufe von getmessages sind nicht notwendig.
dropmessage: Sendet dem Server eine Textzeile (Msg), die den Namen des aufrufenden Clients und seine aktuelle Systemzeit sowie ggf. irgendeinen Text beinhaltet, zudem die zugeordnete (globale) Nummer der Textzeile (INNr) und seine Sendezeit (erstellt mit erlang:now(), TSclientout).
getmsgid: Fragt beim Server die aktuelle Nachrichtenummer ab. self() stellt die Rückrufadresse des Redakteur-Clients dar. Als Rückgabewert erhält er die aktuelle und eindeutige Nachrichtennummer (Number).
Kollisionen:
add message protocol
Bei der Initialisierung des Clients (z.B. beim Aufruf) wird seine Lebenszeit gesetzt. Ist diese Zeit erreicht, terminiert sich der Client.
zuerst editor, dann wieder leser
wie zwischen beiden switchen?
Der Leser-Client fragt nach der Rolle als Redakteur-Client solange aktuelle Textzeilen beim Server ab, bis er alle erhalten hat und stellt sie in seiner GUI dar. Alle unbekannten Textzeilen werden ihm also einzeln übermittelt bzw. pro Anfrage erhält er nur genau eine unbekannte Textzeile. (Leser-Client und Redakteur-Client kennen sich eigentlich nicht, werden jedoch sequentiell ausgeführt!). Der Leser-Client merkt sich die vom Server erhaltenen Nachrichtennummern und fügt einer als Leser-Client erhaltenen Nachricht, die durch sein Redakteur-Client erstellt wurde, die Zeichenfolge ******* an, etwa 6te_Nachricht. C Out: 11.11 21:12:58,720|(6); HBQ In: 11.11 21:12:58,720| DLQ In:11.11 21:13:01,880|.*******; C In: 11.11 21:13:07,190|
Der Lese-Client wertet die mitgelieferten Zeitstempel mittels der in dem Modul werkzeug.erl vorgegebenen Funktionen (validTS/1, lessTS/2, diffTS/2, now2stringD/1,) aus. Sollte eine Nachricht aus der Zukunft kommen (beim Server von einem Redakteur-Client (TSclientout,TShbqin), beim Lese-Client vom Server (TSdlqin,TSdlqout)) ist dies mit der entsprechenden Zeitdifferenz (diffTS/2, now2stringD/1,) der Zeichenkette mit anzufügen.
Um Nachrichten zu empfangen:
ClientPID ! {reply, Message, Terminated}
und terminate
transported messages have this format:
Ein Redakteur-Client sendet in bestimmten Abständen, d.h. alle **** Sekunden, eine Textzeile an den Server, die seinen Namen (sein Rechnernamen (zB lab18), die Praktikumsgruppe (zB 1) und die Teamnummer (zB 03), also "lab18103" beinhalten) und seine aktuelle Systemzeit (die der Sendezeit enstprechen soll) beinhaltet und ggf. anderen Text, zum Beispiel 0-client@lab18-<0.1313.0>-C-1-03: 22te_Nachricht. Sendezeit: 16.05 18:01:30,769|(22);.Diese **** Sekunden Wartezeit sind zwischen der Anforderung einer eindeutigen Nachrichtennummer beim Server und vor dem senden der Nachricht an den Server vorzunehmen.
Der Abstand von **** Sekunden wird nach dem Senden von 5 Textzeilen jeweils um ca. 50% per Zufall vergrößert oder verkleinert. Die Zeit **** darf nicht unter 2 Sekunde rutschen.
Der Redakteur-Client fragt nach dem Senden von 5 Textzeilen eine eindeutige Nachrichtennummer beim Server ab, ohne ihm eine zugehörige Nachricht zu übermitteln. In seinem log ist dies zu vermerken, etwa: 121te_Nachricht um 16.06 09:55:43,525| vergessen zu senden ******
<PraktikumsgruppenID><TeamID><Nummer des ggT-Prozess><Nummer des Starters>
)example for sendy: sendy: 585 (495924); berechnet als neues Mi 429.
initial reading phase:
read for frame size seconds
-> determine which station number is still free, choose that number to send (that is done)
other reading phases:
read for
frame size - (frame size / station count) seconds
-> enter sending phase
Start the nameservice with a port as start parameter
take random slot from the free ones
send only in the middle of my time slot : currentTime % (slot * (frame-size / slots-count) / 2) = 0
wait until my slot is over: currentTime % (slot * (frame-size / slots-count) ) = 0
start reading messages
Der Server verwendet drei ADTs: HBQ (Datei hbq.erl), DLQ (Datei dlq.erl) und CMEM (Datei cmem.erl) als Gedächtnis für die Leser-Clients. Diese dürfen hauptsächlich nur als Erlang-Liste ([ ]) realisiert werden! Als Hilfsstrukturen dürfen Tupel eingesetzt werden. Dazu sind die weiter unten aufgeführten Vorgaben zu beachten!
Die HBQ ist als entfernte ADT zu implementieren. Ihre Schnittstelle ist daher durch Nachrichtenformate beschrieben. Die DLQ oder das CMEM sind als lokale ADT zu implementieren. Daher sind deren Schnittstellen durch Funktionen beschrieben. Intern kann die DLQ bzw. das CMEM jedoch als externer Prozess realisiert werden!
Im Folgenden wird die Schnittstelle des CMEM des Servers beschrieben. Das CMEM darf nur vom Server aus angesprochen werden!
/* Initialisieren des CMEM */
initCMEM(RemTime,Datei)
/* Löschen des CMEM */
delCMEM(CMEM)
/* Speichern/Aktualisieren eines Clients in dem CMEM */
updateClient(CMEM,ClientID,NNr,Datei)
/* Abfrage welche Nachrichtennummer der Client als nächstes erhalten darf */
getClientNNr(CMEM,ClientID)
initCMEM(RemTime,Datei): initialisiert den CMEM. RemTime gibt dabei die Zeit an, nach der die Clients vergessen werden Bei Erfolg wird ein leeres CMEM zurück geliefert. Datei kann für ein logging genutzt werden.
delCMEM(CMEM): löscht den CMEM. Bei Erfolg wird ok zurück geliefert.
updateClient(CMEM,ClientID,NNr,Datei): speichert bzw. aktualisiert im CMEM den Client ClientID und die an ihn gesendete Nachrichtenummer NNr. Datei kann für ein logging genutzt werden.
getClientNNr(CMEM,ClientID): gibt die als nächstes vom Client erwartete Nachrichtennummer des Clients ClientID aus CMEM zurück. Ist der Client unbekannt wird 1 zurück gegeben.
sync time dependent on the received messages and the stations class
Die Stationen sollen in die Klassen A und B unterteilt werden. Die Zeiten sollen grundsätzlich auf UTC basieren.
Die Uhr einer Station der Klasse A wird als hinreichend genau betrachtet. Die Uhren dieser Stationen sollen sich im Rahmen der Möglichkeiten untereinander synchronisieren. Beim Start soll eine anfängliche Abweichung von der UTC einstellbar sein.
Die Uhren der Stationen der Klasse B gelten als nicht hinreichend genau. Sie müssen sich mit den Uhren von Stationen der Klasse A synchronisieren.
Da die dem Server zugestellten Textzeilen bzgl. der Nummerierung in zusammenhängender Reihenfolge erscheinen sollen und Nachrichten mit Textzeilen verloren gehen können bzw. in nicht sortierter Reihenfolge eintreffen können, arbeitet der Server intern mit einer Deliveryqueue (DLQ) und einer Holdbackqueue (HBQ).
In der Deliveryqueue stehen die Nachrichten, die an Clients ausgeliefert werden können, maximal *** viele Textzeilen. Dies wird durch die Größe der Deliveryqueue vorgegeben.
In der Holdbackqueue stehen alle Textzeilen, die nicht ausgeliefert werden dürfen.
Der Server verwendet drei ADTs: HBQ (Datei hbq.erl), DLQ (Datei dlq.erl) und CMEM (Datei cmem.erl) als Gedächtnis für die Leser-Clients. Diese dürfen hauptsächlich nur als Erlang-Liste ([ ]) realisiert werden! Als Hilfsstrukturen dürfen Tupel eingesetzt werden. Dazu sind die weiter unten aufgeführten Vorgaben zu beachten!
Die HBQ ist als entfernte ADT zu implementieren. Ihre Schnittstelle ist daher durch Nachrichtenformate beschrieben. Die DLQ oder das CMEM sind als lokale ADT zu implementieren. Daher sind deren Schnittstellen durch Funktionen beschrieben. Intern kann die DLQ bzw. das CMEM jedoch als externer Prozess realisiert werden!
Wenn in der Holdbackqueue von der Anzahl her mehr als 2/3-tel an echten Nachrichten enthalten sind, als durch die vorgegebene maximale Anzahl an Nachrichten in der Deliveryqueue stehen können, dann wird, sofern eine Lücke besteht, diese Lücke zwischen Deliveryqueue und Holdbackqueue mit genau einer Fehlernachricht geschlossen, etwa: ***Fehlernachricht fuer Nachrichtennummern 11 bis 17 um 16.05 18:01:30,580|. Es werden keine weiteren Lücken innerhalb der Holdbackqueue behandelt! In dem Sinne wird die Holdbackqueue in diesem Fall nicht zwingend geleert. Die Fehlernachrciht ist nur durch eine entsprechende Zeichenkette in der Nachricht zu erkennen. Ansonsten hat sie das Format einer ganz normalen Nachricht, d.h. das System kann eine Fehlernachricht nach Speicherung in der DLQ nicht mehr als solche erkennen!
in der ausführlich beschrieben wird, wie das System zu starten ist!
params:
log eveverything or log nothing
documentation for the starter
should receive multicast datagrams
https://docs.oracle.com/javase/tutorial/networking/datagrams/broadcasting.html
send in time slot middle with the message from the queue packed into datagram
kill the communicator: shutdown server thread and thread pool
instance of objectbroker to null
display received message onto console
MSG_List := [NNr,Msg,TSclientout,TShbqin,TSdlqin,TSdlqout]:
[Integer X String X 3-Tupel X 3-Tupel X 3-Tupel X 3-Tupel]
so TS should be 3-Tupel, but erlang:now() does not return 3-Tupel and werkzeug:timeMilliSecond() also does not return 3-Tupel
so how should the timestamps be generated? why 3-tupel?
client nameservice interface in mware_lib
rebind blocks the stream
Start server socket at given port
Object servant, String name
create proxy class that implements the stub and calls the methods over the orb remotely
resolve an alias to object
narrowcast should make the proxy from the given object ref
call local object that is found by the alias in local registry of nameserviceproxy
<PraktikumsgruppenID><TeamID><Nummer des ggT-Prozess><Nummer des Starters>
, also z.B. ist in der Praktikumsgruppe 4 von dem Team 03 ein zweiter ggT-Prozess von ihrem ersten Starter gestartet worden, so erhält dieser ggT-Prozess den Namen 4321. In der Kommunikation mit externen Prozessen wird dieser Name als atom verwendet, wenn er nicht als Absender dient (From)!read messages from stdin
message bytes from vessel
send to in channel of station
start the server, create a client, rebind something
resolve the reference
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.