diff options
| author | Paul Buetow <paul@buetow.org> | 2008-08-24 23:49:11 +0000 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2008-08-24 23:49:11 +0000 |
| commit | 8136eac3bda1192646f8e464dd50bd11d82fa080 (patch) | |
| tree | fdc03cbe30c51b621f57ffcb5f1cff20f513d072 /LaTeX/chapters | |
| parent | 366112998354a75975bc82be0915067ef7eb7292 (diff) | |
moved stuff
Diffstat (limited to 'LaTeX/chapters')
| -rw-r--r-- | LaTeX/chapters/anhang-a.tex | 22 | ||||
| -rw-r--r-- | LaTeX/chapters/ausblick.tex | 23 | ||||
| -rw-r--r-- | LaTeX/chapters/einleitung.tex | 68 | ||||
| -rw-r--r-- | LaTeX/chapters/header.tex | 212 | ||||
| -rw-r--r-- | LaTeX/chapters/implementierung.tex | 735 | ||||
| -rw-r--r-- | LaTeX/chapters/protokolle.tex | 756 | ||||
| -rw-r--r-- | LaTeX/chapters/simulator.tex | 370 | ||||
| -rw-r--r-- | LaTeX/chapters/titelseite.tex | 119 |
8 files changed, 0 insertions, 2305 deletions
diff --git a/LaTeX/chapters/anhang-a.tex b/LaTeX/chapters/anhang-a.tex deleted file mode 100644 index e9222e0..0000000 --- a/LaTeX/chapters/anhang-a.tex +++ /dev/null @@ -1,22 +0,0 @@ -\chapter{Akronyme}
-
-\begin{acronym}
-\acro{API}{Application Programming Interface}
-\acro{BSD}{Berkeley Software Distribution}
-\acro{GIMP}{GNU Image Manipulation Program}
-\acro{GNU}{GNU's Not UNIX}
-\acro{GUI}{Graphical User Interface}
-\acro{GVim}{Graphical Vi IMproved}
-\acro{HTTPS}{Hypertext Transfer Protocol Secure}
-\acro{IP}{Internet Protocol}
-\acro{JRE}{Java Runtime Environment}
-\acro{NID}{Nachrichten-Identifikationsnummer}
-\acro{PDF}{Protable Document Format}
-\acro{PID}{Prozess-Identifikationsnummer}
-\acro{RTT}{Round Trip Time}
-\acro{SDK}{Software Development Kit}
-\acro{SVN}{Subversion}
-\acro{TCP}{Transmission Control Protocol}
-\acro{UDP}{User Datagram Protocol}
-\acro{VS}{Verteilte Systeme}
-\end{acronym}
diff --git a/LaTeX/chapters/ausblick.tex b/LaTeX/chapters/ausblick.tex deleted file mode 100644 index 5959e7a..0000000 --- a/LaTeX/chapters/ausblick.tex +++ /dev/null @@ -1,23 +0,0 @@ -\chapter{Ausblick}
-
-Es wurde erfolgreich ein Simulator für die Simulation verteilter Systeme entwickelt. Der Simulator hat bereits 10 implementierte Protokolle zur Auswahl eingebaut. Zudem steht dem Anwender ein sehr komfortables Protokoll-API zur Verfügung, womit der Entwicklung neuer Protokolle quasi keine Grenzen gesetzt sind.
-
-Darüber hinaus verfügt der Simulator über eine Vielzahl von sehr flexiblen Einstellungsmöglichkeiten. Für jede Simulation lassen sich somit komplett andere Konfigurationen verwenden. Jeder beteiligte Prozess hat wiederum eigene lokale Einstellungen, wo sich auch jedes Protokoll für jeden Prozess separat einstellen lässt. Die Anzahl und Flexibilität der möglichen Szenarien wird dadurch um einen sehr großen Faktor erweitert.
-
-Mit dem Ereigniseditor gibt es eine komfortable Möglichkeit eigene Szenarien zu programmieren um sie anschließend zu Simulieren. Hierbei kann entweder auf die bereits enthaltenen Protokolle oder auf selbst implementierte Protokolle zugegriffen werden. Alle dazugehörigen Einstellungen und programmierten Ereignisse lassen sich vom Anwender für eine spätere Wiederverwendung plattformunabhängig abspeichern. Somit können auch abgespeicherte Szenarien beispielsweise an Kommilitonen weitergegeben werden oder für eine spätere Präsentierung zwischengespeichert werden. Durch den Logfilter lassen sich mit Hilfe von regulären Ausdrücken nur die relevanten Lognachrichten anzeigen, was die Analyse einer Simulation erheblich vereinfacht. Weitere Funktionen wie Lamport- und Vektor-Zeitstempel sowie Anti-Aliasing runden den Simulator ab.
-
-Durch den objektorientierten Aufbau ist der Simulator relativ einfach erweiterbar, was nicht nur das Protokoll-API betrifft. Insgesamt wurde an den meisten Stellen darauf geachtet, dass zu einem sp\"{a}teren Zeitpunkt Erweiterungen einfließen k\"{o}nnten. Insbesondere soll die Serialisierung von Objekten r\"{u}ckw\"{a}rtskompatibel bleiben, da sonst bei jeder neuen Simulatorversion alle Simulationen erneut angelegt und abgespeichert werden m\"{u}ssten.
-
-Hätte für diese Diplomarbeit noch mehr Zeit zur Verfügung gestanden, dann h\"{a}tten einige der folgenden Funktionen (hier in alphanumerisch sortierter Reihenfolge aufgelistet) auch Einzug halten k\"{o}nnen:
-
-\begin{itemize}
- \item Die M\"{o}glichkeit Protokolle zu entwickeln ohne den kompletten Quelltext des Simulators vorliegen zu haben. Protokollklassen als separate Bibliothek einzubinden, die dynamisch geladen werden k\"{o}nnen.
- \item Die Simulationsdauer beliebig lang machen zu können. Dazu müsste die Klasse \textit{VSSimulatorVisualisation} entlang der Zeitachse scrollbar gemacht werden, so dass der Benutzer für eine nachträgliche Betrachtung des Simulationsverlaufes zu jeder beliebigen Position zurückspringen kann.
- \item Eine Zoomfunktion für die Simulationsvisualisierung einzubauen.
- \item Im Ereigniseditor selbst auch periodische Ereignisse programmierbar zu machen. Bisher kann nur jeder Ereigniseintritt separat programmiert werden oder auf Protokoll-Interne Wecker zurückgegriffen werden.
- \item Lamport- und Vektor-Zeitstempel als Ereigniseintrittskriterien verwenden zu können.
- \item Tiefere Schichten des OSI-Referenzmodells simulieren können, wie z.B. TCP, UDP, IP, ...
- \item Weitere Funktionen einzubauen, wie z.B. das Anklicken einer Nachrichtenlinie, was zu der jeweiligen Nachricht alle verfügbaren Informationen anzeigt und welche gegebenenfalls vom Benutzer editiert werden können.
-\end{itemize}
-
-Da der Simulator höchstwahrscheinlich unter einer Open Source Lizenz freigegeben wird, werden die einen oder anderen Funktionen nachträglich eingebaut werden. Kommilitonen werden auch herzlich dazu eingeladen sein sich an diesem Software-Projekt zu beteiligen. Als Vorbild sei hier der CPU-Simulator M32 \cite{M32}, der von Prof. Oßmann an der Fachhochschule Aachen entwickelt wurde, genannt. Hier existieren bereits einige Erweiterungen und Verbesserungen der Ursprungsversion, die von den Studenten angefertigt wurden. Für die Entwicklung des VS-Simulators wurde keine proprietäre Software verwendet, so dass jeder kostenlosen Zugriff auf die dazugehörigen Tools hat.
diff --git a/LaTeX/chapters/einleitung.tex b/LaTeX/chapters/einleitung.tex deleted file mode 100644 index f7954a4..0000000 --- a/LaTeX/chapters/einleitung.tex +++ /dev/null @@ -1,68 +0,0 @@ -\newpage -~ -\thispagestyle{empty} -\newpage -\chapter{Einleitung} - -\section{Motivation} - -In der Literatur findet man viele verschiedene Definitionen eines verteilten Systems. Vieler dieser Definitionen unterschieden sich untereinander, so dass es schwer fällt eine Definition zu finden, die als Alleinige als die Richtige gilt. Andrew Tanenbaum und Marten van Steen w\"{a}hlten für die Beschreibung eines verteilten Systems die folgende lockere Charakterisierung: - -\cite{Tanenbaum} \textit{``Ein verteiltes System ist eine Menge voneinander unabhängiger Computer, die dem Anwender wie ein einzelnes, kohärentes System erscheinen''} - -Der Anwender muss sich nur mit dem lokalen, vor ihm befindlichen Computer auseinandersetzen, während die Software des lokalen Computers die reibungslose Kommunikation mit den anderen beteiligten Computern des verteilten Systems sicherstellt. - -Diese Diplomarbeit soll den Anwendern die Betrachtung von verteilten Systemen aus einer anderen Perspektive erleichtern. Hierbei wird nicht die Sichtweise eines Endbenutzers eingenommen, sondern es sollen die Funktionsweisen von Protokollen und deren Prozesse in verteilten Systemen begreifbar gemacht und gleichzeitig alle relevanten Ereignisse eines verteilten Systems transparent dargestellt werden. - -Um dieses Ziel zu erreichen soll, insbesondere f\"{u}r Lehr- und Lernzwecke an der Fachhochschule Aachen, ein Simulator entwickelt werden. Mit dem Simulator sollen Protokolle aus den verteilten Systemen mit ihren wichtigsten Einflussfaktoren anhand von Simulationen nachgeblidet werden k\"{o}nnen. Gleichzeitig muss für eigene Experimente ein großer Spielraum zur Verfügung stehen, wobei es keine Beschränkung auf eine feste Anzahl von Protokollen geben darf. Es ist also wichtig, dass es dem Anwender ermöglicht wird eigene Protokolle zu entwerfen. - -\section{Grundlagen} - -Für das Grundverständnis werden im Folgenden einige Grundlagen erläutert. Eine Vertiefung findet erst in den späteren Kapiteln statt. - -\subsubsection{Client/Server Modell} - -\begin{figure}[htbp] - \centering - \fbox{\includegraphics{images/client-server}} - \caption{Client/Server Modell} - \label{fig:ClientServer} -\end{figure} - -Der Simulator basiert auf dem Client/Server-Prinzip. Jede Simulation besteht in der Regel aus einen teilnehmenden Client und einen Server, die miteinander über Nachrichten kommunizieren (s. Abb. \ref{fig:ClientServer}.). Bei komplexen Simulationen können auch mehrere Clients und/oder Server mitwirken. - -\subsubsection{Prozesse und deren Rollen} - -Ein verteiltes System wird anhand von Prozessen simuliert. Jeder Prozess nimmt hierbei eine oder mehrere Rollen ein. Beispielsweise kann ein Prozess die Rolle eines Clients einnehmen und ein weiterer Prozess die Rolle eines Servers. Die M\"{o}glichkeit einem Prozess die Client- und Serverrolle gleichzeitig zuzuweisen ist ebenso gegeben. Ein Prozess k\"{o}nnte auch die Rollen mehrerer Server und Clients gleichzeitig einnehmen. Um einen Prozess zu kennzeichnen, besitzt jeder eine \textbf{eindeutige} Prozess-Identifikationsnummer (PID). - -\subsubsection{Nachrichten} - -In einem verteilten System müssen Nachrichten verschickt werden können. Eine Nachricht kann von einem Client- oder Serverprozess verschickt werden und kann beliebig viele Empfänger haben. Der Inhalt einer Nachricht hängt vom verwendeten Protokoll ab. Was unter einem Protokoll zu verstehen ist, wird später behandelt. Um eine Nachricht zu kennzeichnen, besitzt jede Nachricht eine \textbf{eindeutige} Nachrichten-Identifikationsnummer (NID). - -\subsubsection{Lokale und globale Uhren} - -In einer Simulation gibt es \textbf{genau eine} globale Uhr. Sie stellt die aktuelle und \textbf{immer korrekte} Zeit dar. Eine globale Uhr geht nie falsch. - -Zudem besitzt jeder beteiligte Prozess eine eigene lokale Uhr. Sie stellt die aktuelle Zeit des jeweiligen Prozesses dar. Im Gegensatz zu der globalen Uhr können lokale Uhren eine falsche Zeit anzeigen. Wenn die Prozesszeit nicht global-korrekt ist (nicht der globalen Zeit gleicht, bzw. eine falsche Zeit anzeigt), dann wurde sie entweder im Laufe einer Simulation neu gestellt, oder sie geht wegen einer Uhrabweichung falsch. Die Uhrabweichung gibt an, um welchen Faktor die Uhr falsch geht. Hierauf wird später genauer eingegangen. - -\begin{figure}[htbp] - \centering - \includegraphics{images/client-server-protokolle} - \caption{Client/Server Protokolle} - \label{fig:ClientServerProtokolle} -\end{figure} - -Neben den normalen Uhren sind auch die Vektor-Zeitstempel sowie die logischen Uhren von Lamport von Interesse. Für die Vektor- und Lamportzeiten gibt es hier, im Gegensatz zu der normalen Zeit, keine globalen Äquivalente. Konkrete Beispiele zu den Lamport- und Vektorzeiten werden später in Kapitel 3.11.1. behandelt. - -\subsubsection{Ereignisse} - -Eine Simulation besteht aus der Hintereinanderausführung von endlich vielen Ereignissen. Beispielsweise kann es ein Ereignis geben, welches einen Prozess eine Nachricht verschicken lässt. Denkbar wäre auch ein Prozessabsturzereignis. Jedes Ereignis tritt zu einem bestimmten Zeitpunkt ein. Ereignisse mit selber Eintrittszeit werden vom Simulator direkt hintereinander ausgeführt. Den Anwender des Simulators hindert dies jedoch nicht, da Ereignisse aus ihrer Sicht parallel ausgeführt werden. - -\subsubsection{Protokolle} - -Eine Simulation besteht auch aus der Anwendung von Protokollen. Es wurde bereits erwähnt, dass ein Prozess die Rollen von Servern und/oder Clients annehmen kann. Bei jeder Server- und Clientrolle muss zusätzlich das dazugehörige Protokoll spezifiziert werden. Ein Protokoll definiert, wie ein Client und ein Server Nachrichten verschickt, und wie bei Ankunft einer Nachricht reagiert wird. Ein Protokoll legt auch fest, welche Daten in einer Nachricht enthalten sind. Ein Prozess verarbeitet eine empfangene Nachricht nur, wenn er das jeweilige Protokoll versteht. - -In Abbildung \ref{fig:ClientServerProtokolle}. sind 3 Prozesse dargestellt. Prozess 1 unterstützt serverseitig das Protokoll ``A'' und clientseitig das Protokoll ``B''. Prozess 2 unterstützt clientseitig das Protokoll ``A'' und Prozess 3 serverseitig das Protokoll ``B''. Das heißt, dass Prozess 1 mit Prozess 2 via Protokoll ``A'' und mit Prozess 3 via Protokoll ``B'' kommunizieren kann. Die Prozesse 2 und 3 sind zueinander inkompatibel und können voneinander erhaltene Nachrichten nicht verarbeiten. - -Clients können nicht mit Clients, und Server nicht mit Servern kommunizieren. Für eine Kommunikation wird stets mindestens ein Client und ein Server benötigt. Diese Einschränkung kann aber umgangen werden, indem Prozesse ein gegebenes Protokoll sowohl server- als auch clientseitig unterstützen (vgl. Broadcast Protokoll in Kap. 3.3.). - diff --git a/LaTeX/chapters/header.tex b/LaTeX/chapters/header.tex deleted file mode 100644 index 5286aa9..0000000 --- a/LaTeX/chapters/header.tex +++ /dev/null @@ -1,212 +0,0 @@ -% % Diploma thesis template 2005 -% -% author: lukas.silberbauer(at)gmx.at -% based upon "Diplomarbeit mit LaTeX" by Tobias Erbsland -% -% published under the terms of -% -% ---------------------------------------------------------------------------- -% "THE BEER-WARE LICENSE": -% <lukas.silberbauer(at)gmx.at> wrote this file. As long as you retain this -% notice you can do whatever you want with this stuff. If we meet some day, -% and you think this stuff is worth it, you can buy me a beer in return. -% ---------------------------------------------------------------------------- - -% -% header.tex -% -\documentclass[% - pdftex,% PDFTex verwenden - a4paper,% A4 Papier - oneside,% Einseitig - bibtotocnumbered,% Literaturverzeichnis nummeriert einfügen - idxtotoc,% Index ins Verzeichnis einfügen - halfparskip,% Europäischer Satz mit abstand zwischen Absätzen - chapterprefix,% Kapitel anschreiben als Kapitel - %headsepline,% Linie nach Kopfzeile - %footsepline,% Linie vor Fusszeile - 12pt% Größere Schrift, besser lesbar am bildschrim -]{scrbook} - - -% -% Paket für die Indexerstellung. -% -\usepackage{makeidx} - -% -% Paket für Übersetzungen ins Deutsche -% -\usepackage[german, english]{babel} - -% -% Pakete um Latin1 Zeichnensätze verwenden zu können und die dazu -% passenden Schriften. -% -\usepackage[latin1]{inputenc} -\usepackage[T1]{fontenc} - -% -% Paket zum Erweitern der Tabelleneigenschaften -% -\usepackage{array} - -% -% Paket um Grafiken einbetten zu können -% -\usepackage{graphicx} - -% -% Spezielle Schrift verwenden. -% -\renewcommand{\encodingdefault}{T1} -%\renewcommand{\familydefault}{goudysans} -\renewcommand{\familydefault}{\sfdefault} - - -% -% Zeilenabstand einstellen -% -\usepackage{setspace} -\onehalfspacing -%\doublespacing - -%\setlength{\baselineskip}{24pt} -%\renewcommand{\baselinestretch}{1.5} - -% -% define variables -% -\def\maintitle#1{\gdef\maintitle{#1}} -\def\subtitle#1{\gdef\subtitle{#1}} - -% -% Zeilenumbruch bei Bildbeschreibungen. -% -\setcapindent{1em} - -% -% kopf und fusszeilen -% -\pagestyle{headings} - -% -% mathematische symbole aus dem AMS Paket. -% -\usepackage{amsmath} -\usepackage{amssymb} - -% -% Type 1 Fonts für bessere darstellung in PDF verwenden. -% -\usepackage{mathptmx} % Times + passende Mathefonts -\usepackage[scaled=.75]{helvet} % skalierte Helvetica als \sfdefault -\usepackage{courier} % Courier als \ttdefault - -% -% Paket um Textteile drehen zu können -% -\usepackage{rotating} - -\usepackage{verbatim,framed} -\usepackage{moreverb} - -% -% Für Acronyme -% -\usepackage{acronym} - -% -% Package für Farben im PDF -% -%\usepackage{color} -\usepackage[dvipsnames]{color} -\usepackage[dvipsnames,svgnames]{pstricks} - -% Fuer bilder am seitenrand -%\usepackage{sidecap} -%\usepackage{floatfit} -%\usepackage{float} - - -% -% Paket für Links innerhalb des PDF Dokuments -% -\definecolor{LinkColor}{rgb}{0,0,0.5} - -\usepackage[% -pdfauthor={Paul B\"{u}tow}, -bookmarks=true, % PDF bookmarks allowed. NB! The level depth of bookmarks is the same as in the TOC. -unicode=true, % PDF bookmarks in Unicode. -bookmarksnumbered=true, % Section numbers in PDF bookmarks. -bookmarksopenlevel=1, % The open level in PDF bookmarks. -hyperindex=true, % Hyperlinked index. -colorlinks=true, % Links are marked as coloured text, not coloured box. -linkcolor=linkc, % The colour for in-document links (e.g. in the table of contents). -citecolor = citec, % The colour for bibliographic citations. -urlcolor=urlc, % The colour for hyperlinks to the Net. -pdfpagelayout=OneColumn % Continuous page scrolling. -]{hyperref} -\hypersetup{colorlinks=true,% - linkcolor=LinkColor,% - citecolor=LinkColor,% - filecolor=LinkColor,% - menucolor=LinkColor,% - pagecolor=LinkColor,% - urlcolor=LinkColor} - -% -% Paket um Listings sauber zu formatieren. -% -\usepackage[savemem]{listings} -\lstloadlanguages{TeX} - -% -% --------------------------------------------------------------------------- -% Listing Definationen für PHP Code -% -\definecolor{lbcolor}{rgb}{0.85,0.85,0.85} -\lstset{language=[LaTeX]TeX, - numbers=left, - stepnumber=1, - numbersep=5pt, - numberstyle=\tiny, - breaklines=true, - breakautoindent=true, - postbreak=\space, - tabsize=2, - basicstyle=\ttfamily\footnotesize, - showspaces=false, - showstringspaces=false, - extendedchars=true, - backgroundcolor=\color{lbcolor}} - -% --------------------------------------------------------------------------- -% Neue Umgebungen -% --------------------------------------------------------------------------- - -\newenvironment{ListChanges}% - {\begin{list}{$\diamondsuit$}{}}% - {\end{list}} - -\newenvironment{code}% -{% -\definecolor{shadecolor}{named}{LightYellow}% -\topsep=0ex\relax -\framed -\small -\verbatim -}% -{% -\endverbatim -\endframed -}% - -% -% Index erzeucgen -% -\makeindex - -% -% EOF -% diff --git a/LaTeX/chapters/implementierung.tex b/LaTeX/chapters/implementierung.tex deleted file mode 100644 index 7e29634..0000000 --- a/LaTeX/chapters/implementierung.tex +++ /dev/null @@ -1,735 +0,0 @@ -\chapter{Implementierung}
-
-In diesem Kapitel wird auf die Implementierung des Simulators eingegangen. Der Simulator wurde in der Programmiersprache Java entwickelt. Bei der Betrachtung der Zielgruppe wird klar, dass Java für die gestellte Aufgabe die geeignetste Programmiersprache ist. Der Simulator ist somit auf jedem Betriebssystem ausf\"{u}hrbar, für das es eine JRE (Java Runtime Environment) gibt. Da an der Fachhochschule Aachen die Programmiersprache Java gelehrt wird, sollten die Studenten die M\"{o}glichkeit haben durch eigene Erweiterungen des Simulators Protokolle entwerfen zu k\"{o}nnen. Der Simulator wurde mit dem derzeit aktuellsten Java SDK (Software Development Kit) in der Version 6 (1.6) entwickelt.
-
-\begin{table}
- \fbox{
- \begin{tabular}{l|l}
- \textbf{Paketname} & \textbf{Beschreibung} \\
- \hline
- \textit{core} & Klassen für Prozesse und Nachrichten\\
- \textit{core.time} & Klassen für Zeitformate\\
- \textit{events} & Basisklassen für Ereignisse\\
- \textit{events.implementations} & Implementierungen von Ereignissen\\
- \textit{events.internal} & Implementierungen von internen Ereignissen\\
- \textit{exceptions} & Klassen für Fehlerbehandlungen\\
- \textit{prefs} & Klassen für die Einstellungen\\
- \textit{prefs.editors} & Klassen für die Editoren\\
- \textit{protocols} & Basisklassen für Protokolle\\
- \textit{protocols.implementations} & Implementierungen von Protokollen\\
- \textit{serialize} & Helferklassen für die Serialisierung von Simulationen\\
- \textit{simulator} & Klassen für die GUI und die Visualisierung\\
- \textit{utils} & Diverse Helferklassen\\
- \end{tabular}
- }
- \caption{Die Paketstruktur}
- \label{tb:Pakete}
-\end{table}
-
-Im Folgenden wird der Quelltext auszugsweise behandelt. Der Quelltext erstreckt sich, einschließlich Kommentare, auf ca. 15.000 Zeilen Text und 61 Dateien. Der Umfang der generierten Quelltext-Dokumentationen im Javadoc-Format ist ca. 2MB groß. Alle folgenden UML-Diagramme stellen zwecks Übersichtlichkeit lediglich die wesentlichen Sachverhalte dar. Alle weiteren Details k\"{o}nnen im Quelltext und der dazugehörigen Dokumentation eingesehen werden. Die Paketstruktur des Quelltextes ist in Tabelle \ref{tb:Pakete}. in alphanumerischer Reihenfolge aufgeführt.
-
-\section{Einstellungen und Editoren}
-
-Der Verlauf einer Simulation ist von einer Vielzahl von Einstellungen abhängig. Da auf diese Einstellungen in Weiteren stets zurückgegriffen wird, werden die dazugeh\"{o}rigen Klassen zuerst betrachtet.
-
-\subsubsection{Einstellungsobjekte}
-
-In Abbildung \ref{fig:PackagePrefs}. ist der Aufbau des Pakets \textit{prefs} zu sehen. In einer Instanz der Klasse \textit{VSPrefs} lassen sich viele verschiedene Daten als Variablen für eine spätere Verwendung dynamisch ablegen, damit stellt eine solche Instanz einen Container für diese Daten dar. In einem \textit{VSPrefs}-Objekt speichert der Simulator alle Einstellungen ab. Zudem besitzt jedes Prozessobjekt und jedes Ereignisobjekt für lokale Einstellungen seine eigene Instanz von \textit{VSPrefs}. Später wird gezeigt, wie Protokollobjekte auch als Ereignisse eingesetzt werden, womit Protokolleinstellungen auch in einem \textit{VSPrefs}-Objekt abgespeichert werden k\"{o}nnen. Auch Nachrichtenobjekte besitzt hiervon eine eigene Instanz dieser Klasse, um die zu verschickenden Daten zwischen zu speichern.
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=7cm]{images/prefs}
- \caption{Das Paket \textit{prefs}}
- \label{fig:PackagePrefs}
-\end{figure}
-
-Jede Variable hat einen Datentypen, einen Variablennamen, eine optionale Beschreibung sowie einen Variablenwert. Einige Datentypen unterstützen auch die Angabe von Minimal- und Maximalwerten (z.B. besteht eine Prozentangabe aus einen Integerwert zwischen \textit{0} und \textit{100}), was mit Hilfe der Klasse \textit{VSPrefsRestriction} implementiert wird. Da der Anwender beispielsweise bei Prozent ein \textit{\%} und bei Millisekunden ein \textit{ms} hinter der Variable sehen möchte, kann für jede Variable auch ein optionaler Einheiten-String abgespeichert werden.
-
-Eine Variablenbeschreibung wird für die Darstellung im GUI verwendet, während der Variablenname für die interne Verwendung vom Simulator verwendet wird. Zum Beispiel hat die Variable \textit{message.prob.outage} (Verlustwahrscheinlichkeit einer Nachricht) als Variablenbeschreibung ``Nachrichtenverlustw'keit''. Wenn für eine Variable keine Beschreibung existiert so werden f\"{u}r die Anzeige einer Variable der Datentyp und der Variablenname verwendet. Variablennamen verwenden die in Tabelle \ref{tb:VariablenPraefixe}. angegebenen Präfixkonventionen. Alle verfügbaren Datentypen wurden bereits in Tabelle \ref{tb:VariablenDatentypen}. aufgelistet. Die Klasse \textit{VSPrefs} stellt für alle Variablentypen entsprechende Selektoren zur Verfügung.
-
-Im Folgenden werden einige der existierenden Methoden aufgelistet, eine komplette Liste kann in der Quelltext-Dokumentation eingesehen werden. Die Methoden werden anhand des Integer-Datentyps verdeutlicht. Für Integer stehen in \textit{VSPrefs} folgende Methoden zur Verfügung:
-
-\begin{itemize}
- \setlength{\itemsep}{-2mm}
- \item \textit{void setInteger(String key, Integer val)}
- \item \textit{void setInteger(String key, Integer val, String descr)}
- \item \textit{void setInteger(String key, int val)}
- \item \textit{void setInteger(String key, int val, String descr)}
- \item \textit{Integer getIntegerObj(String key)}
- \item \textit{int getInteger(String key)}
- \item \textit{java.util.Set<String> getIntegerKeySet()}
- \item \textit{void initInteger(String key, int val) }
- \item \textit{void initInteger(String key, int val, String descr) }
- \item \textit{void initInteger(String key, int val, String descr, int minValue, int maxValue) }
- \item \textit{void initInteger(String key, int val, String descr, int minValue, int maxValue, String unit) }
- \item \textit{void initInteger(String key, int val, String descr, VSPrefsRestriction.VSIntegerPrefsRestriction r) }
- \item \textit{void initInteger(String key, int val, String descr, VSPrefsRestriction.VSIntegerPrefsRestriction r, String unit) }
-\end{itemize}
-
-\begin{table}
- \fbox{
- \begin{tabular}{c|l|l}
- \textbf{Variablen-Präfix} & \textbf{Beschreibung} & \textbf{Beispiel}\\
- \hline
- \textit{col} & Farbvariablen & \textit{Color: col.background = Color-Objekt}\\
- \textit{div} & Diverse versteckte Variablen & \textit{Integer: div.window.logsize = 300} \\
- \textit{keyevent} & Variablen, die Tastaturkürzel definieren & \textit{Integer: keyevent.close = KeyEvent.VK\_C} \\
- \textit{lang} & Variablen, die Text beinhalten & \textit{String: lang.activate = aktivieren}\\
- \textit{message} & Variablen, die Nachrichten betreffen & \textit{Integer: message.prob.outage = 0}\\
- \textit{process} & Variablen, die Prozesse betreffen & \textit{Integer: process.prob.crash = 0}\\
- \textit{sim} & Allgemeine Simulationsvariablen & \textit{Integer: sim.process.num = 3}\\
- \end{tabular}
- }
- \caption{Konventionen f\"{u}r Präfixe von Variablennamen}
- \label{tb:VariablenPraefixe}
-\end{table}
-
-Hierbei steht \textit{key} f\"{u}r den Variablennamen- und \textit{val} f\"{u}r den Variablenwert. \textit{descr} ist die optionale Variablenbeschreibung. Es können sowohl Java's Integer-Objekte, als auch Java's primitiver Integer-Typ \textit{int} verwendet werden. Ein \textit{int}-Wert wird intern zwecks Serialisierbarkeit als Integer-Objekt abgespeichert. Die Methode \textit{getIntegerKeySet} gibt alle vorhandenen Integer-Variablennamen (\textit{key}s) als \textit{Set} (s. \cite{Javadoc}) zurück.
-
-Die Klasse \textit{VSPrefs} bietet auch eine Reihe von \textit{initInteger}-Methoden an, welche sich von den \textit{setInteger}-Methoden dadurch unterscheiden, dass sie einer Variable nur einen Wert zuweisen, wenn sie vorher noch nicht initialisiert wurde, was durch \textit{setInteger} oder \textit{initInteger} selbst geschehen sein kann. Eine komplette Übersicht aller Methoden (auch für andere Datentypen) gibt es in der Quelltext-Dokumentation.
-
-Die Klasse \textit{VSPrefs} speichert alle Integervariablen in einem \textit{HashMap<String,Integer>}-Objekt ab, wobei der String-Wert den Variablennamen \textit{key} angibt. Für die Beschreibung \textit{descr}, den Einheiten-String \textit{unit} sowie möglichen Minimal- und Maximalwerte werden separate Instanzen von \textit{HashMap} verwendet. Da die Selektoren von \textit{VSPrefs} synchronisiert sind, können alle \textit{HashMap}s aus verschiednenen Threads gleichzeitig verwendet werden.
-
-Die Klasse \textit{VSSerializablePrefs} implementiert das Interface \textit{VSSerializable} und kann somit durch Serialisierung alle enthaltenen Daten in eine Datei abspeichern bzw. wieder in den Speicher laden (s. Kap. 4.4.6.).
-
-Die Klasse \textit{VSDefaultPrefs} erweitert \textit{VSSerializablePrefs} und initialisiert bei ihrer Instantiierung automatisch alle verfügbaren Simulationsvariablen mit Standardwerten. Hier sind auch alle Spracheinstellungen abgelegt. M\"{o}chte man den Simulator in eine andere Sprache (z.B. Englisch) übersetzen, so muss lediglich diese Datei und die Protokoll-Klassen editiert werden. Die Spracheinstellungen sind einem referenzierten \textit{VSPrefs}-Objekt als versteckte String-Variablen abgespeichert. Spracheinstellungen für Protokolle wurden in den Protokollklassen direkt angegeben, da dies mehr Komfort für Protokollentwickler bedeutet und damit für jede neu programmierte Textausgabe nicht \textit{VSDefaultPrefs.java} editiert werden muss.
-
-Alle Variablen die als Präfix \textit{lang}, \textit{keyevent}, \textit{div} oder \textit{col} im Variablennamen tragen, sind versteckte Variablen und werden in einem Editor nicht angezeigt. Im Expertenmodus sind hingegen nur Variablen, die mit \textit{lang} und \textit{keyevent} beginnen, versteckt. Im Expertenmodus lassen sich so weitere Variablen vom Anwender editieren.
-
-\subsubsection{Editorobjekte}
-
-Wie Variablen intern abgespeichert werden, ist nun bekannt. Für das Editieren von Variablen werden Editor-Objekte verwendet. In Abbildung \ref{fig:PackagePrefsEditors}. ist die Klassenstruktur des dazugehörigen Paketes \textit{prefs.editors} angegeben.
-
-Die Basis eines solchen Editors ist die abstrakte Klasse \textit{VSAbstractEditor}. Jedem Objekt dieser Klasse wird jeweils ein \textit{VSPrefs}-Objekt zum Editieren übergeben. Ein Editor stellt alle verfügbaren nicht-versteckten Variablen des \textit{VSPrefs}-Objektes im GUI dar und bietet die Möglichkeit diese Variablen zu editieren. Für das Editieren von Farbwerten wird auf die Klasse \textit{VSColorChooser} zurückgegriffen. Die Klasse \textit{VSEditorTable} ist für das \textit{JTable}-Objekt aus Java's Swing-Bibliothek (s. \cite{Swing}) zuständig, welches zur graphischen Darstellung aller Variablen eingesetzt wird. Die abstrakte Klasse \textit{VSAbstractBetterEditor} wurde zur Verbesserung der Wartbarkeit des Quelltextes als Zwischenklasse eingef\"{u}hrt.
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=10.5cm]{images/prefs-editors}
- \caption{Das Paket \textit{prefs.editors}}
- \label{fig:PackagePrefsEditors}
-\end{figure}
-
-Die Klasse \textit{VSSimulatorEditor} erlaubt das Editieren der globalen Simulationseinstellungen und der \textit{VSProcessEditor} das Editieren der Prozesseinstellungen sowie der dazugehörigen Protokollvariablen. Da diese beiden Klassen die abstrakte Klasse \textit{VSAbstractBetterEditor} erweitern, können sie mit Hilfe von \textit{VSEditorFrame} in einem separaten Fenster angezeigt werden. Alternativ können die Editoren auch in der Sidebar im Tab ``Variablen'' angezeigt werden. In Abbildung \ref{fig:Simulationseinstellungen}. wurde bereits ein \textit{VSEditorFrame} in Aktion gesehen. In Abbildung \ref{fig:NeueSimulationVariablen}. hingegen wurde ein Prozesseditor in der Sidebar geöffnet. Für Protokolle gibt es keine separate Editor-Klasse, da diese bereits im Prozesseditor editiert werden können. Hierbei iteriert der Prozesseditor über alle dem jeweiligen Prozess verfügbaren Protokollobjekte und fügt deren Variablen in den Prozesseditor ein. Somit erscheinen die Prozess- und die dazugehörigen Protokollvariablen im selben Editor und bieten dem Benutzer eine bessere Übersicht.
-
-\section{Ereignisse}
-
-Für jedes Ereignis existiert eine dazugehörige Klasse, welche die auszuführenden Aktionen implementiert. Eine Instanz einer solchen Klasse wird für eine spätere Ausführung dem Task-Manager (s. Kap. 4.4.3.) übergeben.
-
-Jedes programmierbare Ereignis muss, bevor es vom Simulator verwendet werden kann, in der statischen Klasse \textit{VSRegisteredEvents} registriert werden. Der Simulator bezieht die Liste aller verf\"{u}gbaren Ereignisse aus \textit{VSRegisterEvents}, wodurch der Entwickler bei der Entwicklung eines neuen Ereignisses keine andere Stelle im Quelltext des Simulators \"{a}ndern muss. Da sich die Anzahl der verfügbaren Ereignisklassen des Simulators bei Laufzeit nicht ändert, gibt es keine Instanzen von \textit{VSRegisteredEvents}. Alle Methoden und Klassenattribute sind statisch. Wenn beispielsweise eigene Ereignisse implementiert werden, dann müssen alle neuen Ereignisse per Hand in der Quelltext-Datei \textit{VSRegisteredEvents.java} übernommen werden, und der Simulator muss neu kompiliert werden.
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=13.5cm]{images/events}
- \caption{Das Paket \textit{events.*}}
- \label{fig:PackageEvents}
-\end{figure}
-
-In der Implementierung wird zwischen drei Haupttypen von Ereignissen unterschieden, die jeweils in einem unterschiedlichen Paket liegen (s. Abb. \ref{fig:PackageEvents}.):
-
-\begin{enumerate}
- \item \textit{events.implementations}: In diesem Paket befinden sich alle Ereignisse, die ohne weitere Spezialbehandlung vom Simulator eingesetzt werden können und vom Benutzer direkt im Ereigniseditor programmierbar sind.
- \begin{itemize}
- \item \textit{VSProcessCrashEvent}: Dieses Ereignis lässt den dazugehörigen Prozess abstürzen.
- \item \textit{VSProcessRecoverEvent}: Dieses Ereignis lässt den dazugehörigen Prozess wiederbeleben.
- \end{itemize}
-
- \item \textit{events.internal}: In diesem Paket befinden sich alle Ereignisse, die vom Simulator intern verwendet werden.
- \begin{itemize}
- \item \textit{VSAbstractInternalEvent}: Diese Klasse stellt weitere Methoden zur Verfügung, die von allen internen Ereignissen zur Serialisierung benötigt werden.
- \item \textit{VSMessageReceiveEvent}: Diese Klasse wird für die Ankunft einer Nachricht bei einem Empfängerprozess benötigt. Sie kapselt die eigentliche Nachricht und überprüft, ob der Empfängerprozess das zur Nachricht gehörige Protokoll versteht. Diese Klasse überprüft auch die Simulationseinstellung ``Nur relevante Nachrichten anzeigen'' und entscheidet, ob die Nachricht nach Eintreffen in der Visualisierung und im Logfenster berücksichtigt werden soll oder nicht.
- \item \textit{VSProtocolEvent}: Diese Klasse implementiert gleichzeitig vier verschiedene Ereignisse: Das Aktivieren bzw. Deaktivieren eines Servers oder Clients eines gegebenen Protokolls. Der Ereigniseditor berechnet anhand der verfügbaren Protokolle automatisch alle möglichen Kombinationen und bietet sie dem Anwender in seiner Auswahl an. Für alle dieser vier Ereignisse wird jeweils ein Objekt von \textit{VSProtocolEvent} verwendet, jeweils mit individuellen Attributwerten.
- \item \textit{VSProtocolScheduleEvent}: Diese Klasse wird für die Wecker-Ereignisse benötigt. Wecker-Ereignisse können nur von Protokollen erstellt werden. \textit{VSProtocolScheduleEvent} besitzt eine Referenz auf das verwendete Protokoll und ruft bei Ereigniseintrittszeit entweder die Methode \textit{onServerScheduleStart} bei einem Server- oder \textit{onClientScheduleStart} bei einem Clientprotokoll auf.
- \end{itemize}
- \item \textit{protocols.implementations}: In diesem Paket befinden sich alle Protokollimplementierung. Jedes Protokoll besitzt seine eigene Klasse. Alle Protokolle erben hierbei von der in Abbildung \ref{fig:PackageEvents}. zu sehenden Klasse \textit{protocols.VSAbstractProtocol}. Da \textit{protocols.VSAbstractProtocol} von \textit{events.VSAbstractEvent} erbt, kann ein Protokollobjekt auch als Ereignis eingesetzt werden. Ein solches Ereignis ruft bei Eintritt entweder die Methode \textit{onServerStart} oder die Methode \textit{onClientStart} des Protokolls auf, was einer Server- bzw. einer Clientanfrage entspricht (s. Kap. 4.4.4.).
-\end{enumerate}
-
-Alle Ereignisse, die das Interface \textit{VSCopyableEvent} implementieren, können vom Anwender im Ereigniseditor mit einem Rechtsklick kopiert werden. Des Weiteren müssen sie die Methode \textit{initCopy(VSAbstractEvent copy)} implementieren. Es werden dann alle relevanten Attribute in das neue Ereignis \textit{copy} kopiert.
-
-Alle Ereignisklassen erweitern die abstrakte Klasse \textit{VSAbstractEvent} und müssen folgende abstrakten Methoden implementieren:
-
-\begin{itemize}
- \item \textit{abstract public void onInit()}: Bevor ein Ereignisobjekt vom Simulator verwendet werden kann, muss es initialisiert werden. Diese Methode wird pro Ereignisobjekt nach dessen Erzeugung nur ein einziges Mal ausgeführt.
- \item \textit{abstract public void onStart()}: Diese Methode wird jedes Mal ausgeführt, wenn das Ereignis eintritt. Sie stellt somit das Kernstück eines Ereignisses dar.
-\end{itemize}
-
-Des Weiteren werden folgende nicht-abstrakte Methoden der Klasse \textit{VSAbstractEvent} geerbt:
-
-\begin{itemize}
- \item \textit{public void log(String message)}: Diese Methode schreibt eine Lognachricht in das Simulationslogfenster.
- \item \textit{public VSAbstractEvent getCopy()}: Diese Methode erstellt vom aktuellen Ereignis eine Kopie, auf die eine Referenz zurückgegeben wird. Alle Ereignisse, die kopiert werden können, müssen auch das Interface \textit{VSCopyableEvent} implementieren. Wenn ein Ereignis dies nicht tut und \textit{getCopy()} aufgerufen wird, wird die Ausnahme \textit{exceptions.VSEventNotCopyable} ausgel\"{o}st.
- \item \textit{public VSAbstractEvent getCopy(VSAbstractProcess process)}: Diese Methode erstellt vom aktuellen Ereignis ebenfalls eine Kopie, mit dem Unterschied, dass das Ereignis einem anderen Prozess zugewiesen wird.
-\end{itemize}
-
-Jede Ereignisklasse hat außerdem Zugriff auf folgende Attribute, welche von \textit{VSAbstractEvent} geerbt werden:
-
-\begin{itemize}
- \item \textit{protected VSPrefs prefs}: Eine Referenz auf das Simulationseinstellungsobjekt. Hierüber lassen sich alle Simulationseinstellungen abfragen.
- \item \textit{protected VSAbstractProcess process}: Eine Referenz auf das Prozessobjekt des jeweiligen Prozesses, auf welches das Ereignis angewendet wird.
-\end{itemize}
-
-Da \textit{VSAbstractEvent} die Klasse \textit{VSSerializablePrefs} erweitert, sind alle Ereignisse mit allen ihren Variablen serialisierbar.
-
-\subsubsection{Beispielimplementierung eines Ereignisses}
-
-Im Folgenden wird als Beispiel die Implementierung des Prozessabsturzereignisses \textit{VSProcessCrashEvent} behandelt. Da die dazugehörige Klasse keine Attribute besitzt, verbleibt auch hier die \textit{initCopy}-Methode mit leerem Methodenrumpf. Aufgrund der Serializierbarkeit von Ereignisobjekten muss jede Ereignisklasse in \textit{onInit()} mit \textit{setClassname} den eigenen Klassennamen mitteilen. Bei der Deserialisierung von Ereignissen werden n\"{a}mlich Objekte anhand der Klassennamen dynamisch neu erstellt, wobei der Klassenname stets bekannt sein muss. In \textit{onStart()} wird das eigentliche Ereignis ausgeführt. Hier wird überprüft, ob der Prozess bereits abgestürzt ist und ggf. zum Absturz gebracht.
-\begin{code}
-package events.implementations;
-
-import events.*;
-
-public class VSProcessCrashEvent
-extends VSAbstractEvent implements VSCopyableEvent {
- public void initCopy(VSAbstractEvent copy) {
- }
-
- public void onInit() {
- super.setClassname(super.getClass().toString());
- }
-
- public void onStart() {
- if (!process.isCrashed()) {
- process.isCrashed(true);
- super.log(prefs.getString("lang.crashed"));
- }
- }
-}
-\end{code}
-
-Der Task-Manager (s. Kap. 4.4.3.) überprüft bereits, ob der Prozess abgestürzt ist oder nicht. Das f\"{u}hrt dazu, dass ein Ereignis bei einem abgestürztem Prozess gar nicht erst ausgeführt wird. Die einzige Ausnahme bildet ein Wiederbelebungsereignis (\text{VSProcessRecover}), welches auch dann ausgeführt wird, auch wenn der Prozess abgestürzt ist. Mit \textit{log} wird eine Nachricht (die über \textit{prefs} bezogen wird) in das Logfenster geschrieben.
-
-In der Datei \textit{events/VSRegisteredEvents.java} muss in der \textit{init}-Methode für jedes Ereignis ein Eintrag existieren. Die \textit{init}-Methode wird einmal beim Starten des Simulators ausgeführt:
-
-\begin{code}
-public static void init(VSPrefs prefs_) {
- .
- .
- .
- registerEvent("events.implementations.VSProcessCrashEvent",
- "Prozessabsturz");
- .
- .
- .
-}
-\end{code}
-
-\section{Zeitformate, Prozesse, Nachrichten sowie Task-Manager}
-
-Das Paket \textit{core.time} in Abbildung \ref{fig:PackageCoreTime}. stellt lediglich die Klassen für die Vektor- und Lamport-Zeitstempel zur Verfügung. Für die normale lokale Prozesszeit wird, aus Performance-Gründen, keine eigene Klasse, sondern ein einfaches \textit{long}-Attribut des Prozessobjektes verwendet.
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=7cm]{images/core-time}
- \caption{Das Paket \textit{core.time}}
- \label{fig:PackageCoreTime}
-\end{figure}
-
-In Abbildung \ref{fig:PackageCore}. ist das Paket \textit{core} dargestellt. Für jedes auszuführende Ereignis wird eine Instanz von \textit{VSTask} benötigt, welche die Ereigniseintrittszeit als Attribut abgespeichert. Die Instanz besitzt eine Referenz auf das Ereignisobjekt (\textit{VSAbstractEvent}) sowie das Prozessobjekt (\textit{VSInternalProcess}). Geplante \textit{VSTask}-Instanzen werden dem Task-Manager für eine spätere Ausführung übergeben.
-
-Die Kapselung eines \textit{VSAbstractEvent}-Objektes in einem \textit{VSTask}-Objekt erlaubt es, dass die gleiche \textit{VSAbstractEvent}-Instanz mehrmals im Task-Manager geplant werden kann. Ohne dieser Kapselung gäbe es für jedes Ereignis nur eine einzige mögliche Eintrittszeit. Von dieser Möglichkeit wird z.B. bei den Server- und Clientanfragen eines Protokollobjektes Gebrauch gemacht. Für jedes Protokoll kann der Anwender in einer Simulation beliebig viele Anfragen programmieren, wobei für jede Anfrage stets das selbe Protokollobjekt als Ereignis verwendet wird.
-
-Jede Simulation besitzt genau eine Instanz von \textit{VSTaskManager}. Eine Instanz dieser Klasse stellt den Task-Manager dar. Er verwaltet alle \textit{VSTask}-Instanzen und überprüft periodisch, ob es auszuführende Ereignisse gibt. Der Task-Manager unterscheidet zwischen globalen und lokalen Ereignissen. Hierbei werden alle globalen Ereignisse (gekapselt in einem \textit{VSTask}-Objekt) in einer Prioritäts-Warteschlange (vgl. \cite{Algorithms}, \cite{AlgorithmsC}) abgelegt. Die Prioritäts-Warteschlange stellt hierbei die korrekte Ereigniseintrittsreihenfolge sicher. Da sich die lokalen Zeiten aller beteiligten Prozesse voneinander unterscheiden können, muss für jeden Prozess eine separate lokale Prioritäts-Warteschlange verwendet werden, auf die jedes Prozessobjekt seine eigene Referenz hat. In den lokalen Warteschlangen sind die geplanten lokalen Ereignisse (auch gekapselt in einem \textit{VSTask}-Objekt) abgelegt. Der Task-Manager greift über eine \textit{java.util.ArrayList} auf alle Prozessobjekte zu und kann somit auch auf alle lokalen Warteschlangen zugreifen und diese verwalten.
-
-Eine Instanz von \textit{VSMessage} stellt eine Nachricht dar, die von einem Prozess verschickt wird. Da \textit{VSMessage} von \textit{VSPrefs} erbt, können zwischen zwei Prozessen beliebige Datentypen (s. Tabelle \ref{tb:VariablenDatentypen}.) über eine Nachricht verschickt werden. Anschließend wird für jeden Empfängerprozess ein neues Ereignisobjekt der Klasse \textit{VSMessageReceiveEvent} angelegt, welches eine Referenz der verschickten Nachricht besitzt (s. Abb. \ref{fig:Wrapping}.). Danach wird ein \textit{VSTask}-Objekt instantiiert, in dem die Referenz auf das Ereignisobjekt und das dazugehörige Prozessobjekt sowie die Ereigniseintrittszeit als Attribute gespeichert werden. Das \textit{VSTask}-Objekt wird dann dem Task-Manager übergeben, der das dazugehörige Ereignis ausführt, wenn die Ereigniseintrittszeit eingetroffen ist. Via Java-Polymorphie wird hier das \textit{VSMessageReceiveEvent}-Objekt in ein \textit{VSAbstractEvent} umgewandelt und so in \textit{VSTask} abgelegt.
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=10.0cm]{images/core}
- \caption{Das Paket \textit{core}}
- \label{fig:PackageCore}
-\end{figure}
-
-Erwähnenswert ist auch die Klasse \textit{VSMessageStub}, welche ein \textit{VSMessage} kapselt. Ihr Zweck ist das Verstecken einiger Methoden vor dem Protokoll-API, welches für die Erstellung eigener Protokolle dient. Der Protokoll-Entwickler soll möglichst nichts falsch machen können und deswegen soll dem Protokoll-API ein eingeschränkter Funktionsumfang zur Verfügung gestellt werden. Da sich \textit{VSMessageStub} im selben Paket wie \textit{VSMessage} befindet, kann \textit{VSMessageStub} auf paket-private Methoden von \textit{VSMessage} zugreifen. Protokolle hingegen werden in einem anderen Paket implementiert und haben somit keinen Zugriff auf diese paket-privaten Methoden. Zwar kann der Protokollentwickler ein eigenes \textit{VSMessageStub}-Objekt anlegen, jedoch kann er auf diese Weise besser unterscheiden, auf welche Methoden er zugreifen sollte, und auf welche nicht.
-
-Der Task-Manager speichert anschließend die Nachrichtenempfangsereignisse in seiner globalen Warteschlange. Die Nachricht kommt bei einem Empfängerprozess an, sobald das Ereignis für den Empfang eintritt. Für die korrekte Implementierung der Lamport- und Vektor-Zeitstempel wird jeder Nachricht automatisch eine Referenz auf die Lamport- sowie auf die Vektor-Zeitstempel des sendenden Prozesses als Attribut beigefügt. Für die Überprüfung des Protokolls wird in jeder Nachricht auch der Klassenname des jeweiligen Protokolls abgespeichert.
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=11.0cm]{images/wrapping}
- \caption{Gekapseltes \textit{VSMessage}-Objekt}
- \label{fig:Wrapping}
-\end{figure}
-
-Eine Instanz von \textit{VSInternalProcess} repräsentiert einen simulierten Prozess. Ein \textit{VSInternalProcess} stellt alle vom Simulator intern verwendeten Methoden zur Verfügung, während ein \textit{VSAbstractProcess} lediglich Methoden hat, die der Protokollentwickler für die Erstellung eigener Protokolle verwenden darf. Da \textit{VSAbstractProcess} abstrakt ist und hiervon keine Instanz gebildet werden darf, muss für einen neuen Prozesses stets ein \textit{VSInternalProcess}-Objekt erstellt werden. Via Polymorphie wird dieses Objekt nach \textit{VSAbstractProcess} umgewandelt und so dem Protokoll-API zur Verfügung gestellt. Beispielsweise darf mit \textit{getTasks()} nur vom Simulator intern auf die Prioritäts-Warteschlangen zugegriffen werden, während man im Protokoll-API selbiges vermeiden sollte und dies auch gar nicht direkt möglich ist. Hier wäre auch ein Stub-Objekt \textit{VSProcessStub} denkbar gewesen. Da aber fast jede Millisekunde auf die Methoden von \textit{VSInternalProcess} zugegriffen wird, wurde hier aus Performance-Gründen der Weg über eine Vererbungsstufe preferiert.
-
-Alle einstellbaren Prozessvariablen werden von der Klasse \textit{VSPrefs} geerbt. Damit bei Neuberechnungen die Variablen nicht dauernd über eine \textit{HashMap} von \textit{VSPrefs} zugegriffen werden muss, speichert \textit{VSInternalProcess} aus Performance-Gründen einige Variablen als lokale Kopie ab. Zum Beispiel wird für die lokale Prozesszeit nicht auf das \textit{HashMap<String,Long>}-Objekt von \textit{VSPrefs}, sondern auf das Klassenattribut \textit{private long localTime} zugegriffen. Vor und nach dem Editieren über den Prozesseditor werden die \textit{VSPrefs}, bzw. die lokalen Kopien, auf den neuesten Stand gebracht. Selbiges gilt für weitere Variablen, wie z.B. der Uhrabweichung eines Prozesses.
-
-\subsubsection{Beispiel für die Erstellung von Prozessereignissen}
-
-Anhand der Prozessabsturz- und Wiederbelebungsereignisse lässt sich wie folgt sehr gut demonstrieren, wie intern Ereignisse angelegt werden können:
-\begin{code}
-void createCrashAndRecoverExample(VSTaskManager taskManager,
- VSInternalProcess process) {
- VSAbstractEvent crashEvent = new VSProcessCrashEvent();
- VSTask localTask = new VSTask(process.getTime()+500, process,
- crashEvent, VSTask.LOCAL);
- taskManager.addTask(localTask);
-
- VSAbstractEvent recoverEvent = new VSProcessRecoverEvent();
- VSTask globalTask = new VSTask(2000, process,
- recoverEvent, VSTask.GLOBAL);
- taskManager.addTask(globalTask);
-}
-\end{code}
-
-In diesem Beispiel wurden zwei Ereignisse (Absturz- und Wiederbelebung eines gegebenen Prozesses) angelegt. Das Absturzereignis tritt bei der aktuellen lokalen Prozesszeit plus \textit{500ms} ein, während das Wiederbelebungsereignis bei einer globalen Zeit von \textit{2000ms} stattfindet. Für den Fall, dass das Wiederbelebungsereignis vor dem Absturzereignis eintritt, wird es nicht ausgeführt, da der Prozess noch nicht abgestürzt ist.
-
-\section{Protokoll-API}
-
-In diesem Abschnitt wird auf die Implementierung der Protokolle und das Protokoll-API eingegangen. Im Protokoll-API wird in der Regel nicht direkt auf den Task-Manager und auf die explizite Instantiierung von Ereignisobjekten zurückgegriffen, da dies vom API automatisch durchgef\"{u}hrt wird.
-
-In Abbildung \ref{fig:PackageProtocols}. sind die Pakete \textit{protocols} und \textit{protocols.implementations} dargestellt, welche für die Protokollimplementierungen zuständig sind. \textit{VSAbstractProtocol} stellt lediglich gemeinsame Methoden und Attribute zur Verfügung, die von allen Protokollen verwendet werden können. Jedes Protokoll hat im Paket \textit{protocols.implementations} seine eigene Klasse, die von \textit{VSAbstractProtocol} erbt. Im Prinzip besitzt jedes Prozessobjekt von jedem Protokoll seine eigene Instanz. Bei \textit{10} Protokollen und \textit{3} beteiligten Prozessen werden also \textit{30} Protokollobjekte verwendet. Jedes Protokollobjekt verwaltet sowohl die Server- als auch die Clientseite eines Protokolls auf einmal. Dabei merkt sich \textit{VSAbstractProtocol} anhand einer Flagge, ob der aktuelle Kontext server- oder clientbezogen ist, und führt dementsprechend beim Eintreffen von Ereignissen die Server- bzw. Clientmethoden des Protokolls auf. \textit{VSAbstractProtocol} überprüft auch, ob ein Client oder ein Server überhaupt aktiviert ist.
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=12cm]{images/protocols}
- \caption{Das Paket \textit{protocols.*}}
- \label{fig:PackageProtocols}
-\end{figure}
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=10cm]{images/ss-protokollvariablen}
- \caption{Protokollvariablen im Prozesseditor}
- \label{fig:Protokollvariablen}
-\end{figure}
-
-Es ist bereits bekannt, dass Protokolle im Prozesseditor editierbare Variablen haben können. Da \textit{VSAbstractProtocol} von \textit{VSAbstractEvent} erbt, was wiederum von \textit{VSSerializablePrefs} erbt (und \textit{VSSerializablePrefs} erweitert \textit{VSPrefs}), werden alle Protokollvariablen einfach in die Mutterklasse \textit{VSPrefs} abgelegt. Zum Beispiel kann mit \textit{super.setBoolean(``test'', true);} eine neue Protokollvariable \textit{test} mit dem Standardwert \textit{true} angelegt werden. Diese Variable erscheint dann automatisch im Prozesseditor und kann so vom Anwender konfiguriert werden.
-
-Da der Simulator darauf ausgelegt wurde eigene Protokolle zu implementieren, werden im Folgenden alle verfügbaren Protokoll-API-Methoden etwas ausführlicher als gewohnt beschrieben. Jede Protokollklasse muss die folgenden Methoden implementieren:
-
-\begin{itemize}
- \setlength{\itemsep}{-2mm}
- \item Einen öffentlichen (\textit{public}) Konstruktor. Der Konstruktor muss angeben, ob bei dem gegebene Protokoll der Client oder der Server die Anfragen startet.
- \item \textit{abstract public void onClientInit()}: Bevor das Protokollobjekt benutzt werden kann, muss es initialisiert werden. Diese Methode wird vor dem ersten Verwenden des Protokolls innerhalb einer Simulation ausgeführt. In der Regel werden hier Protokollvariablen unter Verwendung von \textit{VSPrefs} und Attribute der Protokollklasse initialisiert.
- \item \textit{abstract public void onClientReset()}: Diese Methode wird jedes Mal ausgeführt, wenn die Simulation zurückgesetzt wird.
- \item \textit{abstract public void onClientStart()}: Diese Methode wird nur benötigt, wenn der Client immer die Anfragen startet. Diese Methode generiert in der Regel immer eine Clientanfrage, die via \textit{VSMessage}-Objekt an alle anderen beteiligten Prozesse verschickt wird.
- \item \textit{abstract public void onClientRecv(VSMessage message)}: Diese Methode wird jedes Mal aufgerufen, wenn eine Servernachricht \textit{message} bei dem Client eintrifft.
- \item \textit{abstract public void onClientSchedule()}: Diese Methode wird jedes Mal ausgeführt, wenn ein Weckerereignis eintritt.
- \item \textit{public String toString()}: Diese Methode ist nur optional. Hiermit lassen sich die Lognachrichten eines Protokolls anpassen. Wenn diese Methode in einer Protokollimplementierung ausgelassen wird, so wird stets die \textit{toString}-Methode der Mutterklasse \textit{VSAbstractProtocol} verwendet. Bei Verwendung wird empfohlen die Logausgabe lediglich wie folgt zu erweitern:
- \begin{code}
-public String toString() {
- return super.toString() + "; Neue Loginformationen";
-}
- \end{code}
- Hierbei wird jede Lognachricht, die das aktuelle Protokoll betrifft, um die Ausgabe \textit{; Neue Loginformation} erweitert.
-\end{itemize}
-
-Für alle hier aufgelisteten Client-Methoden sind auch die korrespondierenden Server-Methoden anzugeben. Die Server-Methoden sind analog zu den Client-Methoden aufgebaut, wobei lediglich \textit{Client} durch \textit{Server} ausgetauscht werden muss.
-
-Jede Protokollklasse erbt folgende Methoden von \textit{VSAbstractProtocol}, welche vom Protokollentwickler verwendet werden können:
-
-\begin{itemize}
- \setlength{\itemsep}{-2mm}
- \item \textit{pubic void sendMessage(VSMessage message)}: Hiermit verschickt das Protokoll eine Nachricht.
- \item \textit{pubic final boolean hasOnServerStart()}: Stellt fest, ob der Server- oder der Client bei dem aktuellen Protokoll die Anfragen startet.
- \item \textit{pubic final boolean isServer()}: Hiermit lässt sich bestimmen, ob der aktuelle Prozess das aktuelle Protokoll serverseitig aktiviert hat.
- \item \textit{pubic final boolean isClient()}: Hiermit lässt sich bestimmen, ob der aktuelle Prozess das aktuelle Protokoll clientseitig aktiviert hat.
- \item \textit{pubic final void scheduleAt(long time)}: Diese Methode erstellt einen Wecker, der zur angegebenen Prozesszeit eintritt. Nach Ablauf des Weckers wird, abhängig vom aktuellen Kontext (server- oder clientseitig), \textit{onClientSchedue} bzw. \textit{onServerSchedule} ausgeführt.
- \item \textit{pubic final void removeSchedules()}: Entfernt alle gesetzten Wecker im aktuellen Kontext.
- \item \textit{pubic final int getNumProcesses()}: Gibt die Gesamtzahl an der Simulation beteiligten Prozesse zurück.
-\end{itemize}
-
-Bei der Implementierung von Protokollen kann zusätzlich auf die geerbten Attribute \textit{VSAbstractProcess process} und \textit{VSPrefs prefs} zugegriffen werden. Die verfügbare Methoden von \textit{VSPrefs} wurden bereits behandelt. über \textit{prefs} lassen sich alle globalen Simulationseinstellungen abrufen. Folgende Prozessmethoden dürfen aus dem Protokoll-API auf \textit{process} angewendet werden:
-
-\begin{itemize}
- \setlength{\itemsep}{-2mm}
- \item \textit{public float getClockVariance()}: Gibt die Uhrabweichung zurück.
- \item \textit{public void setClockVariance(float clockVariance)}: Setzt die Uhrabweichung des Prozesses.
- \item \textit{public long getGlobalTime()}: Gibt die aktuelle globale Simulationszeit zurück.
- \item \textit{public long getTime()}: Gibt die aktuelle lokale Prozesszeit zurück.
- \item \textit{public void setTime(long time)}: Setzt die aktuelle lokale Prozesszeit.
- \item \textit{public long getLamportTime()}: Gibt den aktuelle Lamport-Zeitstempel des Prozesses zurück.
- \item \textit{public void setLamportTime(long lamportTime)}: Setzt den aktuellen Lamport-Zeitstempel des Prozesses.
- \item \textit{public void increaseLamportTime()}: Inkrementiert den Lamport-Zeitstempel um eins.
- \item \textit{public void updateLamportTime(long lamportTime)}: Erneuert den Lamport-Zeitstempel (vgl. Kap. 3.11.1.).
- \item \textit{public VSVectorTime getVectorTime()}: Gibt den aktuelle Vektor-Zeitstempel des Prozesses zurück.
- \item \textit{public VSTime[] getLamportTimeArray()}: Gibt die gesamte Lamport-Zeitstempel-Historie des Prozesses zurück. Kann nach VSLamportTime umgewandelt werden.
- \item \textit{public VSTime getVectorTimeArray()}: Gibt die gesamte Vektor-Zeitstempel-Historie des Prozesses zurück. Kann nach VSVectorTime umgewandelt werden.
- \item \textit{public void updateVectorTime(VSVectorTime vectorTimeUpdate)}: Erneuert den Vektor-Zeitstempel (vgl. Kap. 3.11.1.).
- \item \textit{public void increaseVectorTime()}: Inkrementiert den Vektor-Zeitstempel am lokalen Index um eins.
- \item \textit{public int getProcessID()}: Gibt die PID zurück.
- \item \textit{public void setProcessID(int processID)}: Setzt die PID.
- \item \textit{public int getProcessNum()}: Gibt die Prozessnummer zurück. Die Prozessnummer gibt an, um den wievielten Prozess es sich handelt. Die Prozessnummer ist nicht die PID.
- \item \textit{public int getRandomPercentage()}: Gibt einen Zufallswert zwischen \textit{0} und \textit{100} zurück.
- \item \textit{public boolean hasCrashed()}: Gibt \textit{true} zurück, wenn der Prozess während der aktuellen Simulation bereits abgestürzt ist.
- \item \textit{public boolean isCrashed()}: Gibt \textit{true} zurück, wenn der Prozess zur Zeit abgestürzt ist.
- \item \textit{public void isCrashed(boolean isCrashed)}: Hiermit kann man den Prozess abstürzen lassen (\textit{isCrashed = true}) sowie wiederbeleben lassen (\textit{isCrashed = false}).
-\end{itemize}
-
-In der Regel werden durch Protokolle Nachrichten (\textit{VSMessage}) verschickt. Davon dürfen folgende Methoden des Protokoll-API verwendet werden:
-
-\begin{itemize}
- \setlength{\itemsep}{-2mm}
- \item \textit{public VSMessage()}: Der Standardkonstruktor für die Erstellung einer neuen Nachricht.
- \item \textit{public int getMessageID()}: Gibt die Nachrichten-ID zurück.
- \item \textit{public boolean equals(VSMessage message)}: Überprüft, ob eine weitere Nachricht die selbe NID besitzt.
-\end{itemize}
-
-Folgende weitere Methoden von \textit{VSMessage} können nach Erhalt einer Nachricht verwendet werden:
-
-\begin{itemize}
- \setlength{\itemsep}{-2mm}
- \item \textit{public String getName()}: Gibt den Namen des zur Nachricht gehörenden Protokolls zurück.
- \item \textit{public String getProtocolClassname()}: Gibt den Klassennamen des zur Nachricht gehörenden Protokolls zurück.
- \item \textit{public VSAbstractProcess getSendingProcess()}: Gibt eine Referenz auf den Senderprozess zurück.
- \item \textit{public long getLamportTime()}: Gibt den Lamport-Zeitstempel des Senderprozesses zurück.
- \item \textit{public VSVectorTime getVectorTime()}: Gibt den Vektor-Zeitstempel des Senderprozesses zurück.
- \item \textit{public boolean isServerMessage()}: Stellt fest, ob es sich um eine Server- oder eine Clientnachricht handelt.
-\end{itemize}
-
-Wenn über eine Nachricht Daten verschickt werden sollen, so werden die von \textit{VSPrefs} gerbten Methoden verwendet.
-
-\subsubsection{Beispielimplementierung eines Protokolls}
-
-Im Folgenden wird die Implementierung des zuverlässigen Multicast-Protokolls \textit{VSReliableMulticastProtocol.java} beispielhaft gezeigt. Die Funktionsweise des Protokolls wurde bereits in Kapitel 3.10. beschrieben. Client- und Serverseite werden hier in der selben Klasse implementiert.
-
-Im Konstruktor muss stets angegeben werden, ob beim gegebenen Protokoll der Client oder der Server die Anfragen startet. Mit \textit{VSAbstractProtocol.HAS\_ON\_CLIENT\_START} wird dem Simulator mitgeteilt, dass der Client die Anfragen startet. Für \textit{VSAbstractProtocol.HAS\_ON\_SERVER\_START} und Serveranfragen gilt dies analog. Da ein Protokoll auch ein \textit{VSAbstractEvent} ist, muss auch hier mit \textit{setClassname} der Name der Klasse des aktuellen Protokolls angegeben werden:
-
-\begin{code}
-package protocols.implementations;
-
-import java.util.ArrayList;
-import java.util.Vector;
-import protocols.VSAbstractProtocol;
-import core.VSMessage;
-
-public class VSReliableMulticastProtocol
- extends VSAbstractProtocol {
- public VSReliableMulticastProtocol() {
- super(VSAbstractProtocol.HAS_ON_CLIENT_START);
- super.setClassname(super.getClass().toString());
- }
-\end{code}
-
-\textbf{Clientseite des Protokolls}
-
-Das private Klassenattribut \textit{pids} wird für die Zwischenspeicherung beteiligter PIDs benötigt. Hier sind alle PIDs der Prozesse abgelegt, von denen noch Bestätigungsnachrichten erwartet werden. als Standard-PIDs werden \textit{1} und \textit{3} verwendet. Die Methoden \textit{initVector} und \textit{initLong} wurden von \textit{VSPrefs} gerbt und initialisieren die Protokollvariablen \textit{pids} und \textit{timeout}, welche vom Benutzer im Prozesseditor editiert werden können (s. Abb. \ref{fig:Protokollvariablen}.):
-\begin{code}
- private ArrayList<Integer> pids;
-
- public void onClientInit() {
- Vector<Integer> vec = new Vector<Integer>();
- vec.add(1);
- vec.add(3);
-
- super.initVector("pids", vec,
- "PIDs beteiligter Prozesse");
- super.initLong("timeout", 2500,
- "Zeit bis erneute Anfrage", "ms");
- }
-\end{code}
-
-Wenn die Simulation zurückgesetzt wird, dann wird auch das Klassenattribut \textit{pids} neu initialisiert:
-\begin{code}
- public void onClientReset() {
- pids.clear();
- pids.addAll(super.getVector("pids"));
- }
-\end{code}
-
-In der Methode \textit{onClientStart} wird geprüft, ob eine Clientanfrage gestartet werden soll. Ist dies der Fall (d.h. mindestens von einem beteiligten Prozess wurde noch keine Bestätigung erhalten), so wird ein neues Nachrichtenobjekt erstellt. Dieses Objektt wird mit dem Inhalt \textit{Boolean: isMulticast=true} verschickt (intern wird hier für jeden Empfängerprozess ein \textit{VSMessageReceiveEvent} erzeugt). Mit \textit{scheduleAt} wird ein Wecker festgelegt, der vorgibt zu welcher lokalen Prozesszeit die Methode \textit{onClientSchedule} aufgerufen werden soll (intern wird hier ein \textit{VSProtocolScheduleEvent} erzeugt):
-\begin{code}
- public void onClientStart() {
- if (pids.size() != 0) {
- long timeout = super.getLong("timeout")
- + process.getTime();
- super.scheduleAt(timeout);
-
- VSMessage message = new VSMessage();
- message.setBoolean("isMulticast", true);
- super.sendMessage(message);
- }
- }
-\end{code}
-
-Wenn eine Serverantwort eintrifft, dann wird \textit{onClientRecv} aufgerufen. Hier wird überprüft, ob überhaupt noch Multicast-Bestätigungen benötigt werden. Nach dieser Überprüfung wird geschaut, ob es sich bei der Antwort um eine noch nicht eingetroffene Bestätigung handelt. Gegebenenfalls wird dann die jeweilige PID aus \textit{pids} entfernt. Wenn \textit{pids} leer ist, dann wurde von allen beteiligten Prozessen eine Bestätigung erhalten und der Client entfernt mit \textit{removeSchedules} alle seine derzeit programmierten Wecker.
-
-\begin{code}
- public void onClientRecv(VSMessage recvMessage) {
- if (pids.size() != 0 && recvMessage.getBoolean("isAck")) {
- Integer pid = recvMessage.getIntegerObj("pid");
-
- if (pids.contains(pid))
- pids.remove(pid);
- else
- return;
-
- super.log("ACK von Prozess " + pid + " erhalten!");
-
- if (pids.size() == 0) {
- super.log("ACKs von allen beteiligten " +
- " Prozessen erhalten!");
-
- super.removeSchedules();
- }
- }
- }
-\end{code}
-
-Für das erneute Verschicken einer Clientanfrage ruft \textit{onClientSchedule} lediglich die Methode \textit{onClientStart} auf, welche wiederum einen neuen Wecker planen kann:
-\begin{code}
- public void onClientSchedule() {
- onClientStart();
- }
-\end{code}
-
-\textbf{Serverseite des Protokolls}
-
-Die Serverseite des Protokolls speichert im Attribut \textit{ackSent}, ob es bereits eine Bestätigung des Multicasts verschickt hat oder nicht. In diesem Protokoll werden in \textit{onServerInit} keine Initialisierungen vorgenommen. Daher gibt es für den Benutzer auch keine serverseitigen Protokollvariablen zum Editieren. Beim Zurücksetzen der Simulation wird \textit{ackSent} lediglich auf den Ursprungswert \textit{false} gesetzt:
-\begin{code}
- private boolean ackSent = false;
-
- public void onServerInit() { }
-
- public void onServerReset() {
- ackSent = false;
- }
-\end{code}
-
-Erhält der Server eine Clientanfrage, so überprüft er Server, ob es sich um eine Multicast-Nachricht handelte oder nicht. Daraufhin wird dann ggf. die Bestätigungsnachricht mit \textit{Boolean: isAck=true} und der Server-PID verschickt. Je nachdem ob bereits eine Bestätigung verschickt wurde oder nicht, wird eine andere Nachricht in Log erstellt:
-\begin{code}
- public void onServerRecv(VSMessage recvMessage) {
- if (recvMessage.getBoolean("isMulticast")) {
- VSMessage message = new VSMessage();
- message.setBoolean("isAck", true);
- message.setInteger("pid", process.getProcessID());
- super.sendMessage(message);
-
- if (ackSent) {
- super.log("ACK erneut versendet");
- } else {
- super.log("ACK versendet");
- ackSent = true;
- }
- }
- }
-\end{code}
-
-Der Server benutzt in diesem Beispiel keinen Wecker. Dementsprechend hat der Methodenrumpf von \textit{onServerSchedule} keinen Inhalt:
-\begin{code}
- public void onServerSchedule() { }
-}
-\end{code}
-
-\subsubsection{Erstellung eigener Protokolle (Schnelldurchlauf)}
-
-Hier werden alle Schritte zusammengefasst, die für die Erstellung eines eigenen Protokolls \textit{VSMyProtocol} durchgeführt werden müssen. Ein Protokoll-Entwickler muss hierf\"{u}r das Java-SDK und Apache Ant installiert- und den Quelltext des Simulators vorliegen haben.
-
-\begin{enumerate}
- \item VS-Simulator Quelltext beziehen und in das Verzeichnis \textit{vs/sources/protocols/implementations} wechseln.
- \item Das Template-Protokoll \textit{VSDummyProtocol.java} nach \textit{VSMyProtocol.java} kopieren.
- \item \textit{VSDummyProtocol.java} editieren und den Klassennamen dort anpassen (\textit{VSDummyProtocol} $\rightarrow$ \textit{VSMyProtocol}).
- \item In das oberste Verzeichnis \textit{vs/} wechseln.
- \item Die Datei \textit{sources/events/VSRegisteredEvents.java} editieren, und in der \textit{init}-Methode folgende Zeile hinzufügen:
- \begin{code}
-registerEvent("protocols.implementations.VSMyProtocol",
- "Neues Protokoll"); // Name
- \end{code}
- \item Mit dem Befehl \textit{ant compile} die Änderungen übernehmen und mit \textit{ant test} testen, ob der Simulator das Protokoll übernommen hat. Hierbei wird der Simulator direkt aus dem Quellverzeichnis gestartet. ``Neues Protokoll'' sollte nun im Ereigniseditor sichtbar sein und programmiert werden können.
- \item Mit dem Befehl \textit{ant dist} das Archiv \textit{dist/lib/VS-Sim-Latest.jar} erstellen und verwenden.
-\end{enumerate}
-
-Wenn eine Simulatorversion versucht eine abgespeicherte Simulation eines nicht implementierten Protokolls zu laden, dann kommt es unweigerlich zu Laufzeitfehlern. Daher muss mit einem neuen Protokoll also stets auch der neue Simulator ausgeliefert werden.
-
-\section{GUI sowie Simulationsvisualisierung}
-
-Das Paket \textit{simulator} (s. Abb. \ref{fig:PackageProtocols}.) enthält die Implementierung der graphischen Benutzeroberfläche des Simulators. Einzigste Ausnahmen sind die Editorklassen in \textit{prefs.editors} sowie die Klasse \textit{utils.VSFrame}.
-
-Beim Starten des Simulators wird die \textit{main}-Methode, welche sich in \textit{VSMain} befindet, aufgerufen. Sie instantiiert ein \textit{VSDefaultPrefs}-Objekt, in welchem alle Standardeinstellungen des Simulators definiert sind. Anschließend wird ein \textit{VSSimulatorFrame} erzeugt, welches ein Simulatorfenster (s. Abb. \ref{fig:NeuesFenster}.) implementiert. Das Simulatorfenster erstellt für jede neue Simulation jeweils ein Objekt der Klasse \textit{VSSimulator}, wobei jede Simulation im Simulationsfenster einen eigenen Tab besitzt (s. Abb. \ref{fig:NeuErstellteSimulation}., unten links). Jede Simulation besitzt dabei eine eigene Simulationsnummer. Jedes \textit{VSSimulator}-Objekt greift auf die Klasse \textit{VSSimulatorVisualization} zurück, welche die Visualisierung der Simulation realisiert (s. Abb. \ref{fig:Visualisierung}.) .
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=11.0cm]{images/simulator}
- \caption{Das Paket \textit{simulator}}
- \label{fig:PackageProtocols}
-\end{figure}
-
-\textit{VSSimulatorVisualization} greift auf Java's Grafikbibliothek Java2D (siehe \cite{Java2d}, \cite{Java2DAPI}, \cite{Games}) zu und ist zur Optimierung der Performance mit dem Simulationsverlauf stark verzahnt. Klassenattribute, die von Simulationseinstellungen und den Fenstergr\"{o}ßen abhängigig sind, werden so nur dann neu berechnet wenn dies erforderlich ist.
-
-Die Klasse \textit{VSMenuItemStates} wird für die Synchronisierung der graphischen Elemente des GUI's mit dem Status der Simulation verwendet. Abhängig vom Simulationsstatus kann der Benutzer bestimmte Aktionen entweder durchführen oder nicht. Zum Beispiel kann eine Simulation nur pausiert werden, wärend sie abgespielt wird. Alle hier möglichen Aktionen sind bereits aus Kapitel 2.1. bekannt.
-
-Die Klasse \textit{VSCreateTask} wird vom Ereigniseditor verwendet. Der Ereigniseditor (s. Abb. \ref{fig:SidebarMitEreignissen}.) wird in der Klasse \textit{VSSimulator} implementiert. Hinter jeder Ereignisauswahl verbirgt sich ein \textit{VSCreateTask}-Objekt, welches vorgibt wie das ein Ereignis anzulegen ist.
-
-Die Klasse \textit{VSLogging} kapselt f\"{u}r das Loggen von Nachrichten die Attribute eines \textit{JTextArea}-Objektes. In dieser Klasse werden alle Logfunktionen implementiert. Die \textit{JTextArea} wird f\"{u}r die Darstellung dem Simulationsobjekt \textit{VSSimulator} \"{u}bergeben. Für den Logfilter wird auf das Java-Standardpaket \textit{java.util.regex} (s. \cite{Regexp}) zugegriffen. Dadurch können anhand von regulären Ausdrücken in Java-Syntax die Logs gefiltert werden (s. Kap. 2.2.2.).
-
-\subsubsection{Threads und Zeitsynchronisierung}
-
-Der Simulator soll auf die Millisekunde genau simulieren k\"{o}nnen und dabei soll jede simulierte Sekunde relativ zur echten Zeit fortschreiten. Die Simulationsabspielgeschwindigkeit lässt sich bei den Simulationseinstellungen unter ``Abspielgeschwindigkeit der Simulation'' (Float: \textit{sim.clock.speed}) einstellen (s. Kap. 2.4.2.). Hierf\"{u}r muss folgendes berücksichtigt werden:
-
-\begin{itemize}
- \item Das Zeichnen der Visualisierung benötigt pro Aktualisierung einige Millisekunden. Hier werden ständig mathematische Berechnungen wie z.B. die Berechnung einer Nachrichtenlinie oder die automatische Skalierung des Diagramms durchgef\"{u}hrt.
- \item Das Neuberechnen der Simulation benötigt pro Aktualisierung einige Millisekunden. Hier arbeitet insbesondere der Task-Manager, welcher überprüft, ob Ereignisse auszuführen sind.
- \item Jeder simulierte Prozess sollte mit der selben Geschwindigkeit fortschreiten, und dies auf jedem Betriebssystem und auf jeder Architektur. Da Threads auf Betriebssystemebene implementiert sind sind Java-Threads nicht komplett plattformunabhängig. Dadurch kann das Verhalten je nach Betriebssystem und Architekturen variieren. Insbesondere übernimmt das Betriebssystem die Entscheidung, wann welcher Thread arbeiten darf (vgl. \cite{Threads}).
- \item Die Simulationszeit wird stets in Millisekunden angegeben und sie wird intern in einer \textit{long}-Variable abgespeichert. Somit kann eine Simulationszeit immer nur den Wert einer ganze Zahl betragen. Berechnungsrundungsfehler durch \textit{sim.clock.speed} (s. Kap. 2.4.2.) müssen berücksichtigt werden.
- \item Der Simulator soll die komplette CPU des Anwender-Computers nicht konstant auslasten.
-\end{itemize}
-
-Es wurde eine Lösung gewählt, bei der lediglich ein einziger Thread für die Visualisierung und die Berechnung der Simulation zuständig ist. Der Algorithmus verläuft in vereinfachter Form wie folgt ab:
-
-\begin{enumerate}
- \item Die aktuelle simulierte globale Zeit sei $t$ und die globale Zeit wo die Simulation endet sei $e$.
- \item Wenn $t > e$, dann $t := e$ setzen.
- \item Neuberechnen und Zeichnen der Visualisierung zum Zeitpunkt $t$. Die dabei verstrichene Zeit sei $v$.
- \item Wenn $t = e$, dann Simulation beenden.
- \item Für einige Millisekunden den Thread pausieren. Hierbei sei $p$ die beim Schlafen verstrichene Zeit.
- \item
- \begin{verbatim}
-for (i = t; i < t + v + p && i < e; i++)
- Alle Ereignisse des Zeitpunktes i hintereinander ausführen
- \end{verbatim}
- \item Bei Punkt 2 mit neuer Startzeit $t := t + v + p$ weitermachen.
-\end{enumerate}
-
-Zus\"{a}tzlich muss noch die Simulationsvariable \textit{sim.clock.speed} ber\"{u}cksichtigt werden. Sie wurde zur verbesserten Übersicht im obigen Algorithmus nicht extra angegeben. Intern speichert der Simulator jeweils die echte Zeit und die Simulationszeit. Die verstrichenen echten Zeiten werden dabei ständig gemessen und anschließend mit \textit{sim.clock.speed} die neuen tatsächlichen Simulationszeiten berechnet. Die Rundungsfehler werden pro Durchgang in einer \textit{double}-Variable (Fließkommazahl doppelter Genauigkeit) abgespeichert. Wenn der Betrag der Rundungsfehler $>= 1$ ist, dann wird davon der ganzteilige Werteanteil in der Simulationszeit berücksichtigt. F\"{u}r jede lokale Prozesszeit sowie der dazugeh\"{o}rigen lokalen Uhrabweichung wird \"{a}hnlich verfahren.
-
-Jede Simulation besitzt somit seinen eigenen Simulationsthread. Des Weiteren gibt es noch den Java Swing-Thread (s. \cite{Swing}), der für das GUI und f\"{u}r die Anwenderinteraktion zuständig ist. Der Anwender kann zu jedem Zeitpunkt in die Simulation eingreifen, weswegen die Behandlung der Anwendereingriffe synchronisiert wurde.
-
-\section{Serialisierung und Deserialisierung von Simulationen}
-
-Der Anwender kann eine erstellte Simulation im Datei-Menü speichern oder eine bereits abgespeicherte Simulation laden. Hierbei wird von der aus Java angebotenen Möglichkeit Objekte zu Serialisieren Gebrauch gemacht. Im Paket \textit{serialize} (s. Abb. \ref{fig:PackageSerialize}.) befinden sich Hilfsklassen, die die Serialisierung einer Simulation unterst\"{u}tzen.
-
-Da nicht alle Daten f\"{u}r die Speicherung einer Simulation relevant sind, wird nur eine Auswahl von Klassenattributen serialisiert. Zum Beispiel werden alle Simulationseinstellungen serialisiert, nicht jedoch GUI-Objekte. Alle serialisierbaren Klassen implementieren das Interface \textit{VSSerializable} mit folgenden zwei Methoden:
-
-\begin{itemize}
- \item \textit{public void serialize(VSSerialize serialize, ObjectOutputStream oos)}: Diese Methode wird bei jedem Serialisierungsvorgang aufgerufen (Speichern einer Simulation).
- \item \textit{public void deserialize(VSSerialize serialize, ObjectInputStream ois)}: Diese Methode wird bei jedem Deserialisierungsvorgang aufgerufen (Laden einer Simulation).
-\end{itemize}
-
-Die Methoden \textit{serialize} und \textit{deserialize} erhalten neben einem Dateistream auch ein \textit{VSSerialize}-Objekt als \"{U}bergabeparameter. Für jeden Serialisierungsvorgang wird zuerst ein Objekt der Klasse \textit{VSSerialize} erstellt. Eine zu serialisierende Simulation besteht aus einer Vielzahl von einander abhängigen Objekten. Jedes Objekt kann dabei Referenzen auf andere Objekte besitzen. Würde jedes Objekt komplett serialisiert werden, so würden Objekte, auf denen mehrere Referenzen existierten, in mehrfacher Ausführung behandelt werden. Bei Kreisverweisen (Objekt A referenziert Objekt B welches ebenfalls eine Referenz auf Objetkt A besitzt) würde die Serialisierung sogar in einer Endlosschleife enden. \textit{VSSerialize} hilft hierbei dies zu vermeiden und merkt sich Informationen von allen bereits serialisierten Objekten, so dass jedes Objekt genau einmal serialisiert wird. Bei der Deserialisierung hilft die Klasse \textit{VSSerialize} dabei, alle Objekte wieder mit den richtigen Referenzen auszustatten.
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=13cm]{images/serialize}
- \caption{Das Paket \textit{serialize} und serialisierbare Klassen}
- \label{fig:PackageSerialize}
-\end{figure}
-
-Alle Klassen, die \textit{VSSerializePrefs} erweitern, können komfortabel sämtliche Einstellungen serialisieren. Beispielsweise speichert der Simulator alle seine globalen Simulationseinstellungen bei einer Serialisierung automatisch ab. Bei den Prozessen und den Ereignissen (und somit auch Protokollen) gilt selbiges analog.
-
-Abgespeicherte Simulationen sollen auch mit zukünftigen Versionen des Simulators kompatibel bleiben. Deshalb werden alle Objekte aller Klassen, die \textit{VSSerializable} implementieren, nicht komplett serialisiert. Bei der Serialisierung werden nur relevante Klassenattribute, die der Simulationsprogrammierung, und nicht z.B. der GUI-Komponenten angehören, serialisiert. Eine Erweiterung des GUIs muss somit nicht bei den Serialisierungen ber\"{u}cksichtigt werden.
-
-\subsubsection{Beispielimplementierung einer \textit{serialize}-Methode}
-
-Der folgende Quelltext-Ausschnitt zeigt eine Beispielimplementierung von \textit{serialize}:
-
-\begin{code}
- public synchronized void serialize(VSSerialize serialize,
- ObjectOutputStream oos)
- throws IOException {
- oss.writeObject(new Boolean(false)); // flag
- oss.writeObject(attributeOne);
- oss.writeObject(ottributeTwo);
- serialize.setObject("sampleObject", this);
- process.serialize(serialize, oos);
- someOtherSerializableObject.serialize(serialize, oos);
- oss.writeObject(new Boolean(false)); // flag
- }
-\end{code}
-
-Vor und nach der eigentlichen Objektserialisierung wird jeweils eine boolesche Flagge mit dem Standardwert \textit{false} serialisiert. Sobald in einer sp\"{a}teren Simulator-Versionen weitere zu serialisierenden Klassenattribute hinzukommen, dann kann bei der Deserialisierung diese Flagge abgefragt und separat behandelt werden. Somit bleiben ältere bereits abgespeicherte Simulationen stets zu neueren Version des Simulators kompatibel. Wenn eine Flagge auf \textit{true} gesetzt wird, dann kann unter den neuen Attributserialisierungen eine weitere Flagge gesetzt werden, wodurch beliebig viele Erweiterungen in die Serialisierung sukzessiv einbaubar sind.
-
-Das zu serialisierende Objekt besitzt hier lediglich zwei zu serialisierende Attribute. Mit \textit{serialize.setObject} speichert \textit{serialize} eine Referenz auf das aktuelle Objekt ab, worauf folgende Objektserialisierungen zurückgreifen können. Danach wird ein \textit{process} und \textit{someOtherSerializableObject} serialisiert. Die Deserialisierung erfolgt genau in umgekehrter Reihenfolge, wobei ein Objekt von \textit{VSSerialize} hilft die Referenzen auf andere Objekte korrekt zu setzen.
-
-In Abbildung \ref{fig:SequenceSerialize} ist die komplette Sequenz f\"{u}r die Serialisierung (das Abspeichern) einer Simulation angegeben. Zuerst wird \textit{serialize} auf die globalen Simulationseinstellungen (\textit{VSPrefs}) und dem Simulatorobjekt (\textit{VSSimulator}) ausgeführt. Das Simulator-Objekt führt \textit{serialize} wiederum auf das \textit{VSSimulatorVisualization}-Objekt aus. Dort wird jeder Prozess inklusive alle Protokollobjekte serialisiert. Anschließend folgt der Task-Manager mit allen programmierten Ereignissen.
-
-\section{Helferklassen und Klassen für Ausnahmebehandlungen}
-
-Es wurden noch nicht die Klassen der Pakete \textit{utils} (s. Abb. \ref{fig:PackageUtils}.) sowie \textit{exceptions} (s. Abb. \ref{fig:PackageExceptions}.) vorgestellt. \textit{utils} fasst lediglich einige Helferklassen zusammen, die vom restlichen Quelltext verwendet werden.
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=10cm]{images/utils}
- \caption{Das Paket \textit{utils}}
- \label{fig:PackageUtils}
-\end{figure}
-
-\begin{itemize}
- \item \textit{VSFrame}: Alle Objekte, die ein eigenes Swing-Fenster besitzen, erben von der Klasse \textit{VSFrame}. Sie stellt sicher, dass neue Fenster an der richtigen Position der Bildfläche platziert werden und dass Unterfenster (Fenster, die aus einem anderen Fenster heraus geöffnet wurden) automatisch mit geschlossen werden, sobald ihr jeweiliges ``Erzeugerfenster'' geschlossen wird.
- \item \textit{VSAboutFrame}: Dieses Fenster implementiert die ``About-Anzeige'' die im Simulator über das Datei-Menü aufgerufen werden kann.
- \item \textit{VSInfoArea}: Ist für die Textanzeige in \textit{VSAboutFrame} zuständig.
- \item \textit{VSClassLoader}: Diese Klasse wird für die automatische Instanzierung von Ereignisobjekten benötigt, wenn dem Simulator lediglich die Klassennamen (aus \textit{events.VSRegisteredEvents}) bekannt sind.
- \item \textit{VSHelper}: In dieser Klasse befinden sich statische Helfermethoden, die in keine andere Klasse gehören.
- \item \textit{VSPriorityQueue}: Diese Klasse wird für das Verwalten von \textit{core.VSTask}-Objekte im Task-Manager benötigt.
- \item \textit{VSRandom}: Wird für Zufallsereignisse benötigt. Jedes Prozessobjekt besitzt einen solchen eigenen Pseudozufallsgenerator. Diese Klasse setzt gleichzeitig einen eigenen Seed basierend auf der lokalen Systemzeit und anderer Zahlen fest.
- \item \textit{VS3Tupel}: Diese Klasse ist eine Implementierung eines einfach aufgebauten 3-Tupel Datentyps. Alle 3 Elemente können von einem anderen Typ sein, was mit Hilfe der Java-Generics verwirklicht wurde. \textit{VS3Tupel} wird von den Editorklassen für die Generierung von GUI-Elementen benötigt.
-\end{itemize}
-
-\begin{figure}[h]
- \centering
- \includegraphics[width=7.5cm]{images/exceptions}
- \caption{Das Paket \textit{exceptions}}
- \label{fig:PackageExceptions}
-\end{figure}
-
-Im Paket \textit{exceptions} befinden sich Klassen, die für Ausnahmebehandlungen verwendet werden. \textit{VSNotCopyableException} wird während eines Kopierversuch eines nicht-kopierbaren Ereignisses geworfen. \textit{VSNegatieNumberException} wird geworfen, wenn negative Zahlen dort auftreten, wo sie es nicht sollten. Wenn ein Editorobjekt die Benutzereingabe einer Integer-Vektor-Variable nicht parsen kann, so greift es auf \textit{VSParseIntegerVectorException} zurück.
-
-\begin{figure}
- \centering
- \rotatebox{90}{%
- \includegraphics[width=22cm]{images/sequence-serialize}
- }
- \caption{Serialisierungssequenz}
- \label{fig:SequenceSerialize}
-\end{figure}
-
-\section{Programmierrichtlinien}
-
-Die Programmierrichtlinien entsprechen idr. denen aus \cite{OOS} (vgl. auch \cite{Richtlinien}).
-
-Die \textit{main}-Methode befindet sich in der Klasse \textit{simulator.VSMain}.
-\begin{itemize}
- \item Es wird kein Gebrauch vom Java-Standardpaket gemacht. Alle Klassen befinden sich somit in explizit angegebenen Paketen (z.B. \textit{events.implementations}).
- \item Alle Namen von Klassen und Interfaces beginnen mit großen Buchstaben, während alle Variablen-, Methoden- und Attributnamen mit kleinen Buchstaben beginnen. Namen finaler Variablen und Attribute bzw. Konstanten sind komplett in Großbuchstaben gehalten.
- \item Alle Quelltext-Dateien besitzen einen Header, der Informationen der verwendeten Lizenz angibt.
- \item Alle Quelltext-Dateien sind vollständig mit Javadoc dokumentiert.
- \item Der komplette Quelltext inklusive Dokumentation ist in englischer Sprache verfasst.
- \item Eine Quelltext-Datei hat eine maximale Zeilenlänge von 80 Zeichen, was der Standardbreite eines UNIX-Terminals entspricht. Eine Ausnahme stellt die Klasse \textit{prefs.VSDefaultPrefs} dar, denn hier befinden sich auch längere Texte die in Strings abgespeichert werden müssen.
- \item Es werden zuerst Klassen aus der Java-Standardbibliothek importiert, bevor Klassen aus dem VS-Simulator selbst importiert werden.
- \item Für die Einrückung des Quelltextes wird das Tool \textit{astyle} mit den Aufrufparametern \textit{--style=java --mode=java} verwendet. Hierbei wird eine Einrückungslänge von 4 Zeichen verwendet.
- \item Namen aller Klassen und Interfaces tragen als Präfix stets \textit{VS}. Die Abkürzung VS steht hierbei für Verteilte Systeme.
- \item Namen abstrakter Klassen tragen als Präfix stets \textit{VSAbstract} (z.B. \textit{VSAbstractEditor}).
- \item Namen aller Protokollklassen tragen als Postfix \textit{Protocol} (z.B. \textit{VSPingPongProtocol}).
- \item Namen aller Ereignisklassen die keine Protokolle implementieren, tragen als Postfix \textit{Event} (z.B. \textit{VSProcessCrashEvent}).
- \item Namen aller dejenigen Klassen die ein Fenster implementieren, tragen als Postfix \textit{Frame} (z.B. \textit{VSSimulatorFrame}).
- \item Überall wo es erforderlich ist werden Java-Generic-Datentypen verwendet (z.B. \textit{java.util.Vector<Integer>} anstelle von \textit{java.util.Vector}).
-\end{itemize}
-
-\section{Entwicklungsumgebung}
-
-In diesem Teilkapitel soll ein kleiner Einblick in die Umgebung, in der der Simulator entwickelt wurde, gewährt werden. Für diese Diplomarbeit wurde ausschließlich Open Source Software verwendet. Die einzige Ausnahme stellt das Betriebssystem Microsoft Windows XP dar, auf welchem der Simulator zusätzlich getestet wurde. Der Simulator wurde jedoch hauptsächlich unter dem Betriebssystem FreeBSD 7.0, einem Open Source Unix-Derivat, programmiert.
-
-Wie bereits bekannt ist, wurde die Programmiersprache Java von Sun Microsystems in der Version 6 (1.6) als Implementierungssprache für den Simulator gewählt. Für die Quelltextdokumentation wurde Javadoc, für die automatische Quelltexteinrückung astyle und als Java-Referenz kam \cite{Javadoc} zum Einsatz. Als Built-Tool wurde hier auf Apache Ant (s. \cite{AntManual} und \cite{AntIntro}) zur\"{u}ckgegriffen.
-
-Als Versionierungssystem wurde SVN (Subversion) verwendet. Für den Zugriff auf das SVN-Repository mittels HTTPS (Hypertext Transfer Protocol Secure) wurde der Apache-Webserver mit WebDAV-Plugin verwendet. Zudem kam WebSVN als Webschnittstelle des SVN-Repository zum Einsatz. Mozilla Firefox diente dabei dem Betrachten der Javadocs und dem Bedienen der WebSVN-Oberfläche.
-
-Für das Schreiben des Java-Quelltextes wurde Graphical Vi IMproved (GVim) sowie die Entwickungsumgebung Eclipse verwendet. Eclipse bietete bessere Code-Refactoring-Methoden, während GVim mit seiner Flexibilität und schnelleren Editiermöglichkeiten in Verbindung mit seiner Script Engine Vim-Script besonders effektiv ist. Es wurden außerdem das JAutoDoc zur Erstellung von Javadoc-Kommentaren und für die Konnektivität mit dem SVN Server das Subversion-Eclipse-Plugin verwendet. Je nach Anforderung wurde zwischen diesen beiden Umgebungen gewechselt. Für das Verfassen des LaTeX-Dokumentes wurde ebenfalls GVim verwendet.
-
-Für die Erstellung dieses PDF-Dokumentes wurde LaTeX in Verbindung mit dem Built-Tool GNU Make und Rubber verwendet. Eine Rechtschreibüberprüfung wurde mit aspell sowie OpenOffice.org durchgeführt. xPDF diente dabei als PDF-Anzeigeprogramm.
-
-Sämtliche UML-Diagramme wurden mit ArgoUML und \cite{UML} angefertigt und die Screenshots mit The GIMP (GNU Image Manipulation Program) sowie ImageMagick nachbearbeitet. Mit dem zip-Programm wurden alle VS-Simulator Distributionen verpackt.
-
-\subsubsection{Linkliste der verwendeten Software}
-
-\begin{itemize}
- \setlength{\itemsep}{-2mm}
- \item Apache Webserver - \url{http://httpd.apache.org}
- \item ArgoUML - \url{http://argouml.tigris.org}
- \item Eclipse - \url{http://www.eclipse.org}
- \item FreeBSD - \url{http://www.FreeBSD.org}
- \item GNU Make - \url{http://www.gnu.org/software/make}
- \item GVim - \url{http://www.vim.org}
- \item ImageMagick - \url{http://www.imagemagick.org}
- \item Javadoc - \url{http://java.sun.com/j2s2/javadoc}
- \item Mozilla Firefox - \url{http://www.mozilla.com}
- \item OpenOffice.org - \url{http://www.OpenOffice.org}
- \item Rubber - \url{http://www.pps.jussieu.fr/~beffara/soft/rubber}
- \item Sun Java - \url{http://java.sun.com}
- \item The GIMP - \url{http://www.gimp.org}
- \item WebDAV - \url{http://httpd.apache.org/docs/2.0/mod/mod\_dav.html}
- \item WebSVN - \url{http://websvn.tigris.org}
- \item aspell - \url{http://aspell.sourceforge.net}
- \item astyle - \url{http://astyle.sourceforge.net}
- \item xPDF - \url{http://www.foolabs.com/xpdf}
- \item zip - \url{http://www.info-zip.org/Zip.html}
-\end{itemize}
-
diff --git a/LaTeX/chapters/protokolle.tex b/LaTeX/chapters/protokolle.tex deleted file mode 100644 index 7d7f625..0000000 --- a/LaTeX/chapters/protokolle.tex +++ /dev/null @@ -1,756 +0,0 @@ -\chapter{Protokolle und Beispiele}
-
-Im Folgenden werden alle verfügbaren Protokolle behandelt. Wie bereits beschrieben wird bei Protokollen zwischen Server- und Clientseite unterschieden. Server können auf Clientnachrichten, und Clients auf Servernachrichten antworten. Jeder Prozess kann beliebig viele Protokolle sowohl clientseitig als auch serverseitig unterstützen. Theoretisch ist es auch möglich, dass ein Prozess für ein bestimmtes Protokoll gleichzeitig der Server und der Client ist. Der Anwender kann auch weitere eigene Protokolle in der Programmiersprache Java mittels der simulatoreigenen API (Application Programming Interface) erstellen (s. Kap. 4.4.4.).
-Im Programmverzeichnis des Simulators befindet sich das Verzeichnis \textit{saved-simulations} mit Beispielsimulationen. Diese liegen jeweils als serialisierter plattformunabh\"{a}ngiger Java-Bytecode in \textit{.dat}-Dateien vor. Alle Protokolle, bis auf das Beispiel-, Ping Pong- sowie das Broadcast-Protokoll, orientieren sich an den in \cite{Tanenbaum}, \cite{Coul} und \cite{Vorlesung} behandelten Protokollen.
-
-\section{Beispiel (Dummy) Protokoll}
-
-Das Dummy-Protokoll dient lediglich als Vorlage für die Erstellung eigener Protokolle. Bei der Verwendung des Dummy-Protokolls werden bei Auftreten von Ereignissen lediglich Lognachrichten ausgegeben. Es werden aber keine weiteren Aktionen ausgeführt.
-
-\newpage
-\section{Das Ping-Pong Protokoll \small{\textit{(ping-pong.dat, ping-pong-sturm.dat)}}}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-ping-pong}}
- \caption{Das Ping-Pong Protokoll}
- \label{fig:PingPongProto}
-\end{figure}
-
-Bei dem Ping-Pong Protokoll (s. Abb. \ref{fig:PingPongProto}.) werden zwischen zwei Prozessen, Client P1 und Server P2, ständig Nachrichten hin- und hergeschickt. Der Ping-Pong Client startet die erste Anfrage, worauf der Server dem Client antwortet. Auf diese Antwort wird vom Client ebenfalls geantwortet und so weiter. Jeder Nachricht wird ein Zähler mitgeschickt, der bei jeder Station um eins inkrementiert- und jeweils im Logfenster protokolliert wird. In Tabelle \ref{tb:PingPongTasks}. sind alle für dieses Beispiel programmierten Ereignisse aufgeführt.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-ping-pong-sturm}}
- \caption{Das Ping-Pong Protokoll (Sturm)}
- \label{fig:PingPongSturmProto}
-\end{figure}
-
-Wichtig ist, dass Prozess 1 seinen Ping-Pong Client aktiviert, bevor er eine Ping-Pong Clientanfrage startet. Wenn die Eintrittszeiten für die Aktivierung des Protokolls und das Starten der Anfrage identisch sind, ordnet der Task-Manager (s. Kap. 4.4.3.) diese Ereignisse automatisch in der richtigen Reihenfolge an. Bei nicht aktiviertem Ping-Pong Client kann P1 keine Ping-Pong Anfrage starten. Bevor ein Prozess eine Anfrage starten kann, muss er das dazugehörige Protokoll aktiviert haben. Entsprechend gilt dies auch für alle anderen Protokolle. Anhand dieses Beispiels ist erkennbar, dass die noch nicht ausgelieferte Nachrichte grün eingefärbt ist während alle ausgelieferten Nachrichten bereits die Farbe Blau tragen (s. Tabelle \ref{tb:Farben}.).
-
-Werden die Ereignisse wie in Tabelle \ref{tb:PingPongSturmTasks}. vorgegeben, so lässt sich ein Ping-Pong Sturm realisieren. Hier wird ein neuer Prozess P3 eingeführt, der als zusätzlicher Ping-Pong Server agiert. Da auf jede Clientnachricht stets zwei Serverantworten folgen, verdoppelt sich bei jedem Ping-Pong Durchgang die Anzahl der Nachrichten. In Abbildung \ref{fig:PingPongSturmProto}. ist der dazugehörige Simulationsverlauf bis zum Zeitpunkt \textit{12676ms} dargestellt.
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Ereignis} \\
- \hline
- 0 & 1 & Ping Pong Client aktivieren\\
- 0 & 2 & Ping Pong Server aktivieren\\
- 0 & 1 & Ping Pong Clientanfrage starten
- \end{tabular}
- }
- \caption{Programmierte Ping-Pong Ereignisse}
- \label{tb:PingPongTasks}
-\end{table}
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Ereignis} \\
- \hline
- 0 & 1 & Ping Pong Client aktivieren\\
- 0 & 2 & Ping Pong Server aktivieren\\
- 0 & 3 & Ping Pong Server aktivieren\\
- 0 & 1 & Ping Pong Clientanfrage starten
- \end{tabular}
- }
- \caption{Programmierte Ping-Pong Ereignisse (Sturm)}
- \label{tb:PingPongSturmTasks}
-\end{table}
-
-\newpage
-\section{Das Broadcast Protokoll \small{\textit{(broadcast.dat)}}}
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Ereignis} \\
- \hline
- 0000 & 1 & Broadcast Client aktivieren\\
- 0000 & 2 & Broadcast Client aktivieren\\
- 0000 & 3 & Broadcast Client aktivieren\\
- 0000 & 4 & Broadcast Client aktivieren\\
- 0000 & 5 & Broadcast Client aktivieren\\
- 0000 & 6 & Broadcast Client aktivieren\\
- 0000 & 1 & Broadcast Server aktivieren\\
- 0000 & 2 & Broadcast Server aktivieren\\
- 0000 & 3 & Broadcast Server aktivieren\\
- 0000 & 4 & Broadcast Server aktivieren\\
- 0000 & 5 & Broadcast Server aktivieren\\
- 0000 & 6 & Broadcast Server aktivieren\\
- 0000 & 1 & Broadcast Clientanfrage starten\\
- 2500 & 1 & Broadcast Clientanfrage starten
- \end{tabular}
- }
- \caption{Programmierte Broadcast Ereignisse}
- \label{tb:BroadcastSturmTasks}
-\end{table}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-broadcast-sturm}}
- \caption{Das Broadcast Protokoll}
- \label{fig:BroadcastSturmProto}
-\end{figure}
-
-Das Broadcast Protokoll verhält sich ähnlich wie das Ping-Pong Protokoll. Der Unterschied ist, dass sich das Protokoll anhand einer eindeutigen Broadcast-ID merkt, welche Nachrichten bereits verschickt wurden. Jeder Prozess verschickt beim Broadcast Protokoll alle erhaltenen Nachrichten erneut, sofern er sie noch nicht schon einmal verschickt hat.
-
-In diesem Fall wird nicht zwischen Client und Server unterschieden, so dass bei der Ankunft einer Nachricht jeweils die gleiche Aktion durchgef\"{u}hrt wird. Somit lässt sich, unter Verwendung mehrerer Prozesse (s. Abb. \ref{fig:BroadcastSturmProto}.) ein Broadcast erzeugen. P1 ist der Client und startet je eine Anfrage nach \textit{0ms} und \textit{2500ms}. Die Simulationsdauer beträgt hier genau \textit{5000ms}. Da ein Client nur Servernachrichten und ein Server nur Clientnachrichten empfangen kann, ist in dieser Simulation jeder Prozess (s. Tabelle \ref{tb:BroadcastSturmTasks}) gleichzeitig Server und Client.
-
-\newpage
-\section{Das Protokoll zur internen Synchronisierung in einem synchronen System \small{\textit{(int-sync.dat)}}}
-
-Bisher wurden nur Protokolle dargestellt, in denen die beteiligten Prozesse keine Uhrabweichungen hatten. Das Protokoll zur internen Synchronisierung ist ein Protokoll zur Synchronisierung der lokalen Prozesszeit, welches beispielsweise angewendet werden kann, wenn eine Prozesszeit aufgrund einer Uhrabweichung falsch geht. Wenn der Client seine (falsche) lokale Prozesszeit $t_c$ mit einem Server synchronisieren möchte, so schickt er ihm eine Clientanfrage. Der Server schickt als Antwort seine eigene lokale Prozesszeit $t_s$ zurück, womit der Client eine neue und genauere Prozesszeit f\"{u}r sich berechnen kann.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-time-sync}}
- \caption{Das Protokoll zur internen Synchronisierung}
- \label{fig:TimeSyncProto}
-\end{figure}
-
-Hier (s. Abb. \ref{fig:TimeSyncProto}.) stellt P1 den Client und P2 den Server dar. Da die Übertragungszeit $t_u$ einer Nachricht zwischen den vermuteten Werten $t'_{min}$ und $t'_{max}$ liegt, berechnet der Client P1 nach Empfang der Serverantwort seine neue lokale Prozesszeit mit:
-
-\begin{equation*}
- t_c := t_s + \frac{1}{2} (t'_{min} + t'_{max})
-\end{equation*}
-
-Somit wird die lokale Zeit von P1, mit einem Fehler von $< \frac{1}{2} (t'_{max} - t'_{min})$, mit der Serverzeit synchronisiert (siehe \cite{Vorlesung}).
-
-Im Beispiel hat der Clientprozess als Uhrabweichung den Wert \textit{0.1} und der Server hat als Uhrabweichung den Wert \textit{0.0} konfiguriert. Der Client startet, wie in Tabelle \ref{tb:InterneSyncTasks}. angegeben, nach \textit{0ms}, \textit{5000ms} und \textit{10000ms} seiner lokalen Prozesszeit jeweils eine Clientanfrage. In der Abbildung lässt sich erkennen, dass die zweite und die dritte Anfrage nicht synchron zu der globalen Zeit gestartet wurden, was auf die Uhrabweichung von P1 zurückzuführen ist. Nach Simulationsende ist die Zeit von P1 bis auf \textit{15000ms} - \textit{15976ms} = \textit{-976ms} synchronisiert.
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Ereignis} \\
- \hline
- 00000 & 1 & Interne Sync. Client aktivieren \\
- 00000 & 2 & Interne Sync. Server aktivieren\\
- 00000 & 1 & Interne Sync. Clientanfrage starten\\
- 05000 & 1 & Interne Sync. Clientanfrage starten\\
- 10000 & 1 & Interne Sync. Clientanfrage starten\\
- \end{tabular}
- }
- \caption{Programmierte Ereignisse zur internen Synchronisierung}
- \label{tb:InterneSyncTasks}
-\end{table}
-
-\subsubsection{Protokollvariablen}
-
-Dieses Protokoll verwendet folgende zwei clientseitige Variablen, die in den Prozesseinstellungen unter dem Punkt ``Interne Sync. Client'' konfiguriert werden können. Serverseitig gibt es hier keine Variablen.
-
-\begin{itemize}
- \item \textbf{Min. Übertragungszeit} \textit{(Long: 500)}: Gibt den Wert $t'_{min}$ in Millisekunden an
- \item \textbf{Max. Übertragungszeit} \textit{(Long: 2000)}: Gibt den Wert $t'_{max}$ in Millisekunden an
-\end{itemize}
-
-$t'_{min}$ und $t'_{max}$ sind die bei den Protokollberechnungen verwendeten Werte. Sie können sich allerdings von den tatsächlichen Nachrichtenübertragungszeiten $t_{min}$ und $t_{max}$ (s. Kap. 2.4.3.) unterscheiden. Somit lassen sich auch Szenarien simulieren, in denen das Protokoll falsch eingestellt wurde und wo bei der Zeitsynchronisierung große Fehler auftreten können.
-
-\newpage
-\section{Christians Methode zur externen Synchronisierung \small{\textit{(ext-vs-int-sync.dat)}}}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-time-sync-2}}
- \caption{Interne Synchronisierung und Christians Methode im Vergleich}
- \label{fig:TimeSync2Proto}
-\end{figure}
-
-Ein weiteres Protokoll für die Synchronisierung von Uhrzeiten funktioniert nach der Christians Methode zur externen Synchronisierung. Die Christians Methode benutzt die RTT (Round Trip Time), um die Übertragungszeit von einzelnen Nachrichten zu approximieren.
-
-Wenn der Client seine lokale Zeit $t_c$ bei einem Server synchronisieren möchte, so verschickt er eine Anfrage, und misst dabei bis zur Ankunft der Serverantwort die dazugehörige RTT $t_{rtt}$. Die Serverantwort beinhaltet die lokale Prozesszeit $t_s$ des Servers von dem Zeitpunkt an dem der Server die Antwort verschickte. Der Client berechnet dann seine lokale Zeit neu mit:
-
-\begin{equation*}
- t_c := t_s + \frac{1}{2} t_{rtt}
-\end{equation*}
-
-Die Genauigkeit betr\"{a}gt $\pm(\frac{1}{2} t_{rtt} - u_{min}$) wobei $u_{min}$ mit $t_{rtt} < u_{min}$ eine Schranke für eine Nachrichtenübertragung darstellt(s. \cite{Vorlesung}).
-
-Im Prinzip sieht der Verlauf einer Christians-Simulation so aus wie in Abbildung \ref{fig:TimeSyncProto}., daher wird hier auf eine einfache Abbildung vom Christians-Protokoll verzichtet. Viel interessanter ist der direkte Vergleich zwischen dem Protokoll zur internen Synchronisierung und der Christians Methode der externen Synchronisierung (s. Abb. \ref{fig:TimeSync2Proto}.). Hier stellt P1 den Client zur internen Synchronisierung und P3 den Client zur externen Synchronisierung dar. P2 fungiert für beide Protokolle gleichzeitig als Server. P1 und P3 starten jeweils zu den lokalen Prozesszeiten \textit{0ms}, \textit{5000ms} und \textit{10000ms} eine Clientanfrage (s. Tabelle \ref{tb:InterneSync2Tasks}.). P1 und P3 haben als Uhrabweichung einen Wert von \textit{0.1} eingestellt und die Simulationsdauer beträgt insgesamt \textit{15000ms}.
-
-Aus Abbildung \ref{fig:TimeSync2Proto}. ist ersichtlich, dass nach Ablauf der Simulation, P1 seine Zeit bis auf \textit{15000ms} - \textit{14567ms} = \textit{433ms} und P3 seine Zeit bis auf \textit{15000ms} - \textit{15539ms} = \textit{-539ms} synchronisiert hat. In diesem Beispiel hat also das Protokoll zur internen Synchronisierung ein besseres Ergebnis geliefert. Dies ist allerdings nicht immer zwingend der Fall, da nach einer erneuten Simulationsausführung alle Nachrichten jeweils eine neue zufällige Übertragungszeit zwischen $t_{min}$ und $t_{max}$ haben werden, die auf die Zeitsynchronisation mit den einem oder anderem Protokoll jeweils andere Auswirkungen haben k\"{o}nnen.
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Ereignis} \\
- \hline
- 00000 & 1 & Interne Sync. Client aktivieren \\
- 00000 & 1 & Interne Sync. Clientanfrage starten\\
- 00000 & 2 & Christians Server aktivieren\\
- 00000 & 2 & Interne Sync. Server aktivieren\\
- 00000 & 3 & Christians Client aktivieren \\
- 00000 & 3 & Christians Clientanfrage starten\\
- 05000 & 1 & Interne Sync. Clientanfrage starten\\
- 05000 & 3 & Christians Clientanfrage starten\\
- 10000 & 1 & Interne Sync. Clientanfrage starten\\
- 10000 & 3 & Christians Clientanfrage starten\\
- \end{tabular}
- }
- \caption{Programmierte Ereignisse, Vergleich interner und externer Synchronisierung}
- \label{tb:InterneSync2Tasks}
-\end{table}
-
-\newpage
-\section{Der Berkeley Algorithmus zur internen Synchronisierung \small{\textit{(berkeley.dat)}}}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-berkeley}}
- \caption{Der Berkeley Algorithmus zur internen Synchronisierung}
- \label{fig:BerkeleyProto}
-\end{figure}
-
-Der Berkeley Algorithmus zur internen Synchronisierung ist eine weitere Möglichkeit lokale Uhrzeiten abzugleichen. Dies ist das erste Protokoll, wo der Server die Anfragen startet. Der Server fungiert gewissermaßen als Koordinator des Protokolls. Die Clientprozesse sind somit passiv und müssen warten, bis eine Serveranfrage eintrifft. Hierbei muss der Server wissen, welche Clientprozesse an dem Protokoll teilnehmen, was sich in den Protokolleinstellungen des Servers einstellen lässt.
-
-Wenn der Server seine lokale Zeit $t_s$ und auch die Prozesszeiten $t_i$ der Clients ($i = 1, ..., n$) synchronisieren möchte, so verschickt er eine Serveranfrage. $n$ sei hierbei die Anzahl beteiligter Clients. Die Clients senden dann ihre lokalen Prozesszeiten in einer Nachricht zurück zum Server. Der Server hat dabei die RTTs $r_i$ bis zur Ankunft aller Clientantworten gemessen.
-
-Nachdem alle Antworten vorliegen, setzt er zunächst seine eigene Zeit $t_s$ auf den Mittelwert $t_{avg}$ aller bekannten Prozesszeiten (seiner eigenen Prozesszeit eingeschlossen). Die Übertragungszeit einer Clientantwort wird auf die Hälfte der RTT geschätzt und in der Berechnung von $t_{avg}$ wie folgt berücksichtigt:
-\begin{equation*}
- t_{avg} :=
- \frac{1}{n+1} ( t_s +
- \sum_{\substack{
- i=1\\
- }}^n
- \frac{r_i}{2} + t_i
- )
-\end{equation*}
-\begin{equation*}
- t_s := t_{avg}
-\end{equation*}
-
-Anschließend berechnet der Server für jeden Client einen Korrekturwert $k_i := t_{avg} - t_i$, den er jeweils in einer separaten Nachricht an die einzelnen Clients zurückschickt. Diese setzten dann jeweils die lokalen Prozesszeiten auf $t'_i := t'_i + k_i$. Wobei $t'_i$ die lokale, aktuelle Prozesszeit des jeweiligen Clients ist.
-
-Im Beispiel in Abbildung \ref{fig:BerkeleyProto}. gibt es die 2 Clientprozesse P1 und P3 sowie den Serverprozess P2. Der Server startet nach jeweils \textit{0ms} und \textit{7500ms} eine Synchronisierungsanfrage (s. Tabelle \ref{tb:BerkeleyTasks}.). Hier fällt auf, dass der Server stets 2 Korrekturwerte verschickt, die jeweils P1 und P3 erreichen. Es werden hier also pro Synchronisierungsvorgang insgesamt 4 Korrekturwerte ausgeliefert. Eine Korrekturnachricht enthält neben dem Korrekturwert $k_i$ auch die PID des Prozesses, für den die Nachricht bestimmt ist. Indem das Protokoll die PID überprüft verarbeitet ein Client so nur die für ihn bestimmten Korrekturwerte.
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Ereignis} \\
- \hline
- 0000 & 1 & Berkeley Client aktivieren \\
- 0000 & 2 & Berkeley Server aktivieren \\
- 0000 & 3 & Berkeley Client aktivieren \\
- 0000 & 2 & Berkeley Serveranfrage starten\\
- 7500 & 2 & Berkeley Serveranfrage starten\\
- \end{tabular}
- }
- \caption{Programmierte Ereignisse zum Berkeley Algorithmus}
- \label{tb:BerkeleyTasks}
-\end{table}
-\subsubsection{Protokollvariablen}
-
-Dieses Protokoll verwendet folgende serverseitige Variable, die in den Prozesseinstellungen unter dem Punkt ``Berkeley Server'' konfiguriert werden kann. Clientseitig gibt es hierbei keine Einstellungsm\"{o}glichkeiten.
-
-\begin{itemize}
- \item \textbf{PIDs beteiligter Prozesse} \textit{(Integer[]: [1,3])}: Dieser Vektor aus Integerwerten beinhaltet alle PIDs der Berkeley Clientprozesse, mit denen der Berkeley Server die Zeit synchronisieren soll. Das Protokoll funktioniert nicht, wenn hier eine PID angegeben wird die nicht existiert oder die das Berkeley Protokoll clientseitig nicht unterstützt. In diesem Fall würde ewig auf eine (fehlende) Clientantwort gewartet werden.
-\end{itemize}
-
-\newpage
-\section{Das Ein-Phasen Commit Protokoll \small{\textit{(one-phase-commit.dat)}}}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-one-phase-commit}}
- \caption{Das Ein-Phasen Commit Protokoll}
- \label{fig:OnePhaseCommitProto}
-\end{figure}
-
-Das Ein-Phasen Commit Protokoll ist dafür gedacht beliebig vielen Clients zu einer Festschreibung zu bewegen. Im realen Leben könnte dies beispielsweise das Erstellen oder Löschen einer Datei sein, von der auf jedem Client eine lokale Kopie existiert. Der Server ist der Koordinator und auch derjenige, der einen Festschreibewunsch initiiert. Hierbei verschickt der Server periodisch so oft den Festschreibewunsch, bis er von jedem Client eine Bestätigung erhalten hat. Hierf\"{u}r m\"{u}ssen f\"{u}r den Server die PIDs aller beteiligten Clientprozesse sowie ein Wecker f\"{u}r erneutes Versenden des Festschreibewunsches konfiguriert werden.
-
-Die programmierten Ereignisse des Beispiels auf (s. Abb. \ref{fig:OnePhaseCommitProto}.) sind in Tabelle \ref{tb:OnePhaseCommitTasks}. aufgelistet. P1 und P3 simulieren jeweils einen Client und P2 den Server. Damit die Simulation mehrere Festschreibewünsche verschickt, stürzt in der Simulation P1 nach \textit{1000ms} ab und nach \textit{5000ms} steht er wieder zur Verfügung. Die ersten beiden Festschreibewünsche erreichen dadurch P1 nicht und erst der dritte Versuch verläuft erfolgreich. Bevor die Bestätigung von P1 bei P2 eintrifft, läuft jedoch der Wecker erneut ab, so dass ein weiterer Festschreibewunsch versendet wird. Da P1 und P3 jeweils schon eine Bestätigung verschickt haben, wird diese Festschreibewunschnachricht ignoriert. Jeder Client bestätigt auf einen Festschreibewunsch nur ein einziges Mal.
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Ereignis} \\
- \hline
- 0000 & 1 & 1-Phasen Commit Client aktivieren\\
- 0000 & 2 & 1-Phasen Commit Server aktivieren\\
- 0000 & 3 & 1-Phasen Commit Client aktivieren\\
- 0000 & 2 & 1-Phasen Commit Serveranfrage starten\\
- 1000 & 1 & Prozessabsturz\\
- 5000 & 1 & Prozesswiederbelebung
- \end{tabular}
- }
- \caption{Programmierte Ein-Phasen Commit Ereignisse}
- \label{tb:OnePhaseCommitTasks}
-\end{table}
-
-\subsubsection{Protokollvariablen}
-
-Dieses Protokoll verwendet folgende serverseitige Variablen, die in den Prozesseinstellungen unter dem Punkt ``1-Phasen Commit Server'' konfiguriert werden können. Clientseitig gibt es hier keine Variablen.
-
-\begin{itemize}
- \item \textbf{Zeit bis erneute Anfrage} \textit{(Long: timeout = 2500)}: Gibt die Anzahl von Millisekunden an, die gewartet werden sollen, bis der Festschreibewunsch erneut verschickt wird.
- \item \textbf{PIDs beteiligter Prozesse} \textit{(Integer[]: pids = [1,3])}: Dieser Vektor aus Integerwerten beinhaltet alle PIDs der Clientprozesse, die festschreiben sollen.
-\end{itemize}
-
-\section{Das Zwei-Phasen Commit Protokoll \small{\textit{(two-phase-commit.dat)}}}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-two-phase-commit}}
- \caption{Das Zwei-Phasen Commit Protokoll}
- \label{fig:TwoPhaseCommitProto}
-\end{figure}
-
-Das Zwei-Phasen Commit Protokoll ist eine Erweiterung des Ein-Phasen Commit Protokolls. Der Server startet zunächst eine Anfrage an alle beteiligten Clients, ob festgeschrieben werden soll. Jeder Client antwortet dann mit \textit{true} oder \textit{false}. Der Server fragt periodisch so oft nach, bis alle Ergebnisse aller Clients vorliegen. Nach Erhalt aller Abstimmungen überprüft der Server, ob alle mit \textit{true} abgestimmt haben. Für den Fall dass mindestens ein Client mit \textit{false} abgestimmt hat, wird der Festschreibevorgang abgebrochen und als globales Abstimmungsergebnis \textit{false} an alle Clients verschickt. Wenn jedoch alle mit \textit{true} abstimmten, soll festgeschrieben werden. Dabei wird das globale Abstimmungsergebnis \textit{true} verschickt. Das globale Abstimmungsergebnis wird periodisch so oft erneut verschickt, bis von jedem Client eine Bestätigung des Erhalts vorliegt.
-
-In dem Beispiel (s. Abb. \ref{fig:TwoPhaseCommitProto}.) sind P1 und P3 Clients und P2 der Server. Der Server verschickt nach \textit{0ms} seine erste Anfrage (s. Tabelle \ref{tb:TwoPhaseCommitTasks}.). Da diese Simulation recht unübersichtlich ist, liegen in den Tabellen \ref{tb:TwoPhaseCommitLogs}. und \ref{tb:TwoPhaseCommitLogs2}. Auszüge aus dem Logfenster vor. Die Lamport- und Vektor-Zeitstempel sowie die lokalen Prozesszeiten sind hier nicht aufgef\"{u}hrt. Da keine Uhrabweichungen konfiguriert wurden, sind die lokalen Prozesszeiten stets identisch mit der globalen Zeit, weswegen in den Tabellen pro Logeintrag jeweils nur eine Zeit angegeben ist. Anhand der Nachrichten IDs lassen sich dort die einzelnen Sendungen zuordnen. In den Logs wird auch der Inhalt der verschickten Nachricht sowie die dazugehörigen Datentypen aufgeführt. Hier stimmen P1 und P3 jeweils mit \textit{true} ab, das heißt es soll festgeschrieben werden.
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Ereignis} \\
- \hline
- 0000 & 1 & 2-Phasen Commit Client aktivieren\\
- 0000 & 2 & 2-Phasen Commit Server aktivieren\\
- 0000 & 3 & 2-Phasen Commit Client aktivieren\\
- 0000 & 2 & 2-Phasen Commit Serveranfrage starten
- \end{tabular}
- }
- \caption{Programmierte Zwei-Phasen Commit Ereignisse}
- \label{tb:TwoPhaseCommitTasks}
-\end{table}
-
-\subsubsection{Protokollvariablen}
-
-Dieses Protokoll verwendet folgende serverseitige Variablen, die in den Prozesseinstellungen unter dem Punkt ``2-Phasen Commit Server'' konfiguriert werden können:
-
-\begin{itemize}
- \item \textbf{Zeit bis erneute Anfrage} \textit{(Long: timeout = 2500)}: Gibt die Anzahl von Millisekunden an, die gewartet werden sollen, bis der Festschreibewunsch erneut verschickt wird.
- \item \textbf{PIDs beteiligter Prozesse} \textit{(Integer[]: pids = [1,3])}: Dieser Vektor aus Integerwerten beinhaltet alle PIDs der Clientprozesse die über eine Festschreibung abstimmen und anschließend gegebenenfalls festschreiben sollen.
-\end{itemize}
-
-Die folgende Clientvariable kann unter den Prozesseinstellungen unter dem Punkt ``2-Phasen Commit Client'' konfiguriert werden:
-
-\begin{itemize}
- \item \textbf{Festschreibwahrscheinlichkeit} \textit{(Integer: ackProb = 50)}: Gibt die Wahrscheinlichkeit in Prozent an, die der Client mit \textit{true}, also für das Festschreiben, abstimmt.
-\end{itemize}
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Lognachricht} \\
- \hline
-000000 & & Simulation gestartet\\
-\hline
-000000 & 1 & 2-Phasen Commit Client aktiviert\\
-\hline
-000000 & 2 & 2-Phasen Commit Server aktiviert\\
-\hline
-000000 & 2 & Nachricht versendet; ID: 94; Protokoll: 2-Phasen Commit\\
- & & Boolean: wantVote=true\\
-\hline
-000000 & 3 & 2-Phasen Commit Client aktiviert\\
-\hline
-000905 & 3 & Nachricht erhalten; ID: 94; Protokoll: 2-Phasen Commit\\
-\hline
-000905 & 3 & Nachricht versendet; ID: 95; Protokoll: 2-Phasen Commit\\
- & & Integer: pid=3; Boolean: isVote=true; vote=true\\
-\hline
-000905 & 3 & Abstimmung true versendet\\
-\hline
-001880 & 2 & Nachricht erhalten; ID: 95; Protokoll: 2-Phasen Commit\\
-\hline
-001880 & 2 & Abstimmung von Prozess 3 erhalten! Ergebnis: true\\
-\hline
-001947 & 1 & Nachricht erhalten; ID: 94; Protokoll: 2-Phasen Commit\\
-\hline
-001947 & 1 & Nachricht versendet; ID: 96; Protokoll: 2-Phasen Commit\\
- & & Integer: pid=1; Boolean: isVote=true; vote=true\\
-\hline
-001947 & 1 & Abstimmung true versendet\\
-\hline
-002500 & 2 & Nachricht versendet; ID: 97; Protokoll: 2-Phasen Commit\\
- & & Boolean: wantVote=true\\
-\hline
-003006 & 3 & Nachricht erhalten; ID: 97; Protokoll: 2-Phasen Commit\\
-\hline
-003006 & 3 & Nachricht versendet; ID: 98; Protokoll: 2-Phasen Commit\\
- & & Integer: pid=3; Boolean: isVote=true; vote=true\\
-\hline
-003006 & 3 & Abstimmung true versendet\\
-\hline
-003137 & 2 & Nachricht erhalten; ID: 96; Protokoll: 2-Phasen Commit\\
-\hline
-003137 & 2 & Abstimmung von Prozess 1 erhalten! Ergebnis: true\\
-\hline
-003137 & 2 & Abstimmungen von allen beteiligten Prozessen erhalten!\\
- & & Globales Ergebnis: true\\
-\hline
-003137 & 2 & Nachricht versendet; ID: 99; Protokoll: 2-Phasen Commit\\
- & & Boolean: isVoteResult=true; voteResult=true\\
-\hline
-004124 & 1 & Nachricht erhalten; ID: 99; Protokoll: 2-Phasen Commit\\
- \end{tabular}
- }
- \caption{Auszug aus dem Logfenster des Zwei-Phasen Commit Beispiels}
- \label{tb:TwoPhaseCommitLogs}
-\end{table}
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Lognachricht} \\
- \hline
-004124 & 1 & Globales Abstimmungsergebnis erhalten. Ergebnis: true\\
-\hline
-004124 & 1 & Nachricht versendet; ID: 100; Protokoll: 2-Phasen Commit\\
- & & Integer: pid=1; Boolean: isAck=true\\
-\hline
-004354 & 3 & Nachricht erhalten; ID: 99; Protokoll: 2-Phasen Commit\\
-\hline
-004354 & 3 & Globales Abstimmungsergebnis erhalten. Ergebnis: true\\
-\hline
-004354 & 3 & Nachricht versendet; ID: 101; Protokoll: 2-Phasen Commit\\
- & & Integer: pid=3; Boolean: isAck=true\\
-\hline
-004434 & 1 & Nachricht erhalten; ID: 97; Protokoll: 2-Phasen Commit\\
-\hline
-004434 & 1 & Nachricht versendet; ID: 102; Protokoll: 2-Phasen Commit\\
- & & Integer: pid=1; Boolean: isVote=true; vote=true\\
-\hline
-004434 & 1 & Abstimmung true versendet\\
-\hline
-004527 & 2 & Nachricht erhalten; ID: 98; Protokoll: 2-Phasen Commit\\
-\hline
-004975 & 2 & Nachricht erhalten; ID: 101; Protokoll: 2-Phasen Commit\\
-\hline
-005311 & 2 & Nachricht erhalten; ID: 102; Protokoll: 2-Phasen Commit\\
-\hline
-005637 & 2 & Nachricht versendet; ID: 103; Protokoll: 2-Phasen Commit\\
- & & Boolean: isVoteResult=true; voteResult=true\\
-\hline
-006051 & 2 & Nachricht erhalten; ID: 100; Protokoll: 2-Phasen Commit\\
-\hline
-006051 & 2 & Alle Teilnehmer haben die Abstimmung erhalten\\
-\hline
-006766 & 1 & Nachricht erhalten; ID: 103; Protokoll: 2-Phasen Commit\\
-\hline
-006766 & 1 & Globales Abstimmungsergebnis erhalten. Ergebnis: true\\
-\hline
-006766 & 1 & Nachricht versendet; ID: 104; Protokoll: 2-Phasen Commit\\
- & & Integer: pid=1; Boolean: isAck=true\\
-\hline
-007279 & 2 & Nachricht erhalten; ID: 104; Protokoll: 2-Phasen Commit\\
-\hline
-007618 & 3 & Nachricht erhalten; ID: 103; Protokoll: 2-Phasen Commit\\
-\hline
-007618 & 3 & Globales Abstimmungsergebnis erhalten. Ergebnis: true\\
-\hline
-007618 & 3 & Nachricht versendet; ID: 105; Protokoll: 2-Phasen Commit\\
- & & Integer: pid=3; Boolean: isAck=true\\
-\hline
-009170 & 2 & Nachricht erhalten; ID: 105; Protokoll: 2-Phasen Commit\\
-\hline
-010000 & & Simulation beendet
- \end{tabular}
- }
- \caption{Auszug aus dem Logfenster des Zwei-Phasen Commit Beispiels (2)}
- \label{tb:TwoPhaseCommitLogs2}
-\end{table}
-
-\newpage
-\newpage
-\section{Der ungenügende (Basic) Multicast \small{\textit{(basic-multicast.dat)}}}
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Ereignis} \\
- \hline
- 00000 & 2 & Basic Multicast Client aktivieren\\
- 00000 & 3 & Basic Multicast Server aktivieren\\
- 00000 & 2 & Basic Multicast Clientanfrage starten\\
- 02500 & 1 & Basic Multicast Server aktivieren\\
- 02500 & 2 & Basic Multicast Clientanfrage starten\\
- 03000 & 3 & Prozessabsturz\\
- 05000 & 2 & Basic Multicast Clientanfrage starten\\
- 06000 & 3 & Prozesswiederbelebung\\
- 07500 & 2 & Basic Multicast Clientanfrage starten\\
- 10000 & 2 & Basic Multicast Clientanfrage starten\\
- 12500 & 2 & Basic Multicast Clientanfrage starten
- \end{tabular}
- }
- \caption{Programmierte Basic-Multicast Ereignisse}
- \label{tb:BasicMulticastTasks}
-\end{table}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-basic-multicast}}
- \caption{Das Basic-Multicast Protokoll}
- \label{fig:BasicMulticastProto}
-\end{figure}
-
-Das Basic-Multicast Protokoll ist sehr einfach aufgebaut. Im Beispiel in Abbildung \ref{fig:BasicMulticastProto}. sind P1 und P3 Server und P2 der Client. Bei diesem Protokoll startet der Client immer die Anfrage, welche bei diesem Protokoll eine einfache Multicast-Nachricht darstellt. Die Basic-Multicast Server dienen dabei lediglich zum Empfang einer Nachricht. Es werden keine Bestätigungen verschickt. Wie in Tabelle \ref{tb:BasicMulticastTasks}. aufgeführt verschickt P2 alle \textit{2500ms} jeweils eine Multicast-Nachricht, die alle voneinander völlig unabhängig sind.
-
-P1 kann jedoch erst nach \textit{2500ms} Multicast-Nachrichten empfangen, da er vorher das Protokoll nicht unterstützt während P3 von \textit{3000ms} bis \textit{6000ms} abgestürzt ist und in dieser Zeit auch keine Nachrichten empfangen kann. In diesem Beispiel simuliert P1 ein Server, der erst sp\"{a}ter ans Netz angeschlossen wird. Da die Einstellung ``Nur relevante Nachrichten anzeigen'' aktiviert ist, wird die erste Multicast-Nachricht von P2 an P1 nicht dargestellt. Bei jedem Prozess wurde die Nachrichtenverlustwahrscheinlichkeit auf \textit{30} Prozent gestellt, so dass alle in dieser Simulation verschickten Nachrichten mit einer Wahrscheinlichkeit von \textit{30} Prozent ausfallen.
-
-In diesem Beispiel ging die 3. Multicast-Nachricht auf den Weg zu P3- und die 5. sowie 6. Nachricht auf den Weg zu P1 verloren. Lediglich die 4. Multicast-Nachricht hat beide Ziele erreicht.
-
-
-\section{Das zuverlässige (Reliable) Multicast Protokoll \small{\textit{(reliable-multicast.dat)}}}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-reliable-multicast}}
- \caption{Das Reliable-Multicast Protokoll}
- \label{fig:ReliableMulticastProto}
-\end{figure}
-
-Bei dem zuverlässigen (Reliable) Multicast verschickt der Client periodisch so oft seine Multicast-Nachricht, bis er von allen beteiligten Servern eine Bestätigung erhalten hat. Nach jedem erneuten Versuch vergisst der Client, von welchen Servern er bereits eine Bestätigung erhalten hat, wodurch jede erneute Anfrage von allen Teilnehmern aufs Neue best\"{a}tigt werden muss. In dem Beispiel (s. Abb. \ref{fig:ReliableMulticastProto}., Tabelle \ref{tb:ReliableMulticastTasks}., \ref{tb:ReliableMulticastLogs}. und \ref{tb:ReliableMulticastLogs2}.) ist P2 der Multicast-verschickende Client, während P1 und P3 die Server darstellen. Bei \textit{0ms} initiiert der Client seine Multicast-Nachricht. Die Nachrichtenverlustwahrscheinlichkeiten sind bei allen Prozessen auf \textit{30} Prozent eingestellt.
-
-In diesem Beispiel benötigt der Client bis zur erfolgreichen Auslieferung des zuverlässigen Multicasts genau 5 Versuche:
-
-\begin{enumerate}
- \setlength{\itemsep}{-1mm}
- \item Versuch:
- \begin{itemize}
- \setlength{\itemsep}{-2.5mm}
- \item P1 unterstützt das Reliable-Multicast Protokoll noch nicht, und kann somit weder Multicast-Nachricht erhalten noch eine Bestätigung verschicken.
- \item P3 empfängt die Multicast-Nachricht, jedoch geht seine Bestätigungsnachricht verloren.
- \end{itemize}
- \item Versuch:
- \begin{itemize}
- \setlength{\itemsep}{-2.5mm}
- \item P1: Die Multicast-Nachricht geht unterwegs zu P1 verloren.
- \item P3: Die Multicast-Nachricht erreicht P3, aber P3 ist abgestürzt und kann somit keine Nachricht verarbeiten.
- \end{itemize}
- \item Versuch:
- \begin{itemize}
- \setlength{\itemsep}{-2.5mm}
- \item P1 empfängt die Multicast-Nachricht und seine Bestätigung kommt wie geplant bei P2 an.
- \item P3: Die Multicast-Nachricht geht unterwegs zu P3 verloren.
- \end{itemize}
- \item Versuch:
- \begin{itemize}
- \setlength{\itemsep}{-2.5mm}
- \item P1 empfängt die Multicast-Nachricht und seine Bestätigung kommt wie geplant bei P2 an.
- \item P3: Die Multicast-Nachricht erreicht P3, aber P3 ist abgestürzt und kann somit keine Nachricht verarbeiten.
- \end{itemize}
- \item Versuch:
- \begin{itemize}
- \item P1 empfängt die Multicast-Nachricht und seine Bestätigung kommt wie geplant bei P2 an.
- \setlength{\itemsep}{-2.5mm}
- \item P3 empfängt die Multicast-Nachricht und seine Bestätigung kommt wie geplant bei P2 an.
- \end{itemize}
-\end{enumerate}
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Ereignis} \\
- \hline
- 00000 & 3 & Reliable Multicast Server aktivieren\\
- 00000 & 2 & Reliable Multicast Client aktivieren\\
- 00000 & 2 & Reliable Multicast Clientanfrage starten\\
- 02500 & 1 & Reliable Multicast Server aktivieren\\
- 03000 & 3 & Prozessabsturz\\
- 10000 & 3 & Prozesswiederbelebung\\
- \end{tabular}
- }
- \caption{Programmierte Reliable-Multicast Ereignisse}
- \label{tb:ReliableMulticastTasks}
-\end{table}
-
-\subsubsection{Protokollvariablen}
-
-Dieses Protokoll verwendet folgende serverseitige Variablen, die in den Prozesseinstellungen unter dem Punkt ``Reliable Multicast Server'' konfiguriert werden können:
-
-\begin{itemize}
- \item \textbf{Zeit bis erneute Anfrage} \textit{(Long: timeout = 2500)}: Gibt die Anzahl von Millisekunden an, die gewartet werden sollen, bis der Muticast erneut verschickt wird.
- \item \textbf{PIDs beteiligter Prozesse} \textit{(Integer[]: pids = [1,3])}: Dieser Vektor aus Integerwerten beinhaltet alle PIDs der Serverprozesse, die die Multicast-Nachricht erhalten sollen.
-\end{itemize}
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Lognachricht} \\
- \hline
-000000 & & Simulation gestartet\\
-\hline
-000000 & 2 & Reliable Multicast Client aktiviert\\
-\hline
-000000 & 2 & Nachricht versendet; ID: 280; Protokoll: Reliable Multicast;\\
- & & Boolean: isMulticast=true\\
-\hline
-000000 & 3 & Reliable Multicast Server aktiviert\\
-\hline
-001590 & 3 & Nachricht erhalten; ID: 280; Protokoll: Reliable Multicast\\
-\hline
-001590 & 3 & Nachricht versendet; ID: 281; Protokoll: Reliable Multicast\\
- & & Integer: pid=3; Boolean: isAck=true\\
-\hline
-001590 & 3 & ACK versendet\\
-\hline
-002500 & 1 & Reliable Multicast Server aktiviert\\
-\hline
-002500 & 2 & Nachricht versendet; ID: 282; Protokoll: Reliable Multicast\\
- & & Boolean: isMulticast=true\\
-\hline
-003000 & 3 & Abgestürzt\\
-\hline
-005000 & 2 & Nachricht versendet; ID: 283; Protokoll: Reliable Multicast\\
- & & Boolean: isMulticast=true\\
-\hline
-005952 & 1 & Nachricht erhalten; ID: 283; Protokoll: Reliable Multicast\\
-\hline
-005952 & 1 & Nachricht versendet; ID: 284; Protokoll: Reliable Multicast\\
- & & Integer: pid=1; Boolean: isAck=true\\
-\hline
-005952 & 1 & ACK versendet\\
-\hline
-007500 & 2 & Nachricht versendet; ID: 285; Protokoll: Reliable Multicast\\
- & & Boolean: isMulticast=true\\
-\hline
-007937 & 2 & Nachricht erhalten; ID: 284; Protokoll: Reliable Multicast\\
-\hline
-007937 & 2 & ACK von Prozess 1 erhalten!\\
-\hline
-008469 & 1 & Nachricht erhalten; ID: 285; Protokoll: Reliable Multicast\\
-\hline
-008469 & 1 & Nachricht versendet; ID: 286; Protokoll: Reliable Multicast\\
- & & Integer: pid=1; Boolean: isAck=true\\
- \end{tabular}
- }
- \caption{Auszug aus dem Logfenster des Reliable-Multicast Beispiels}
- \label{tb:ReliableMulticastLogs}
-\end{table}
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{c|c|l}
- \textbf{Zeit (ms)} & \textbf{PID} & \textbf{Lognachricht} \\
-\hline
-008469 & 1 & ACK erneut versendet\\
-\hline
-010000 & 2 & Nachricht versendet; ID: 287; Protokoll: Reliable Multicast\\
- & & Boolean: isMulticast=true\\
-\hline
-010000 & 3 & Wiederbelebt\\
-\hline
-010395 & 2 & Nachricht erhalten; ID: 286; Protokoll: Reliable Multicast\\
-\hline
-010995 & 3 & Nachricht erhalten; ID: 287; Protokoll: Reliable Multicast\\
-\hline
-010995 & 3 & Nachricht versendet; ID: 288; Protokoll: Reliable Multicast\\
- & & Integer: pid=3; Boolean: isAck=true\\
-\hline
-010995 & 3 & ACK erneut versendet\\
-\hline
-011213 & 1 & Nachricht erhalten; ID: 287; Protokoll: Reliable Multicast\\
-\hline
-011213 & 1 & Nachricht versendet; ID: 289; Protokoll: Reliable Multicast\\
- & & Integer: pid=1; Boolean: isAck=true\\
-011213 & 1 & ACK erneut versendet\\
-\hline
-011813 & 2 & Nachricht erhalten; ID: 288; Protokoll: Reliable Multicast\\
-\hline
-011813 & 2 & ACK von Prozess 3 erhalten!\\
-\hline
-011813 & 2 & ACKs von allen beteiligten Prozessen erhalten!\\
-\hline
-012047 & 2 & Nachricht erhalten; ID: 289; Protokoll: Reliable Multicast\\
-\hline
-015000 & & Simulation beendet\\
- \end{tabular}
- }
- \caption{Auszug aus dem Logfenster des Reliable-Multicast Beispiels (2)}
- \label{tb:ReliableMulticastLogs2}
-\end{table}
-
-\newpage
-~
-\newpage
-\section{Weitere Beispiele}
-
-Bisher wurden alle verfügbaren Protokolle anhand von Beispielen aufgeführt. Mit dem Simulator lassen sich jedoch noch weitere Szenarien simulieren. Aus diesem Grund soll hier auf weitere Anwendungsbeispiele eingegangen werden.
-
-\subsection{Simulation von Lamport- und Vektor-Zeitstempel}
-
-\cite{Tanenbaum} ``\textit{F\"{u}r viele Zwecke ist es ausreichend, dass sich alle Maschinen \"{u}ber dieselbe Zeit einig sind. Es ist nicht erforderlich, dass diese Zeit auch mit der realen Zeit \"{u}bereinstimmt, wie sie jede Stunde im Radio angek\"{u}ndigt wird.... F\"{u}r eine bestimmte Klasse von Algorithmen ist nur die interne Konsistenz der Uhren wichtig}''.
-
-Uhren die eine solche Zeit angeben, sind auch als logische Uhren bekannt. Zwei davon werden anhand der Lamport- und Vektor-Zeitstempel wie folgt realisiert:
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-berkeley-lamport}}
- \caption{Lamport-Zeitstempel}
- \label{fig:Lamportzeit}
-\end{figure}
-
-Die Vektor- und Lamport-Zeitstempel lassen sich sehr gut am bereits behandeltem Beispiel des Berkeley-Protokoll's (vgl. Kap. 3.6.) demonstrieren. Nach Aktivierung des Lamportzeit-Schalters erscheint bei jedem Ereignis eines Prozesses der aktuelle Lamport-Zeitstempel (s. Abb. \ref{fig:Lamportzeit}.). Jeder Prozess besitzt einen eigenen Lamport-Zeitstempel, der beim Versenden und Erhalten einer Nachricht inkrementiert wird. Jeder Nachricht wird die aktuelle Lamportzeit $t_l(i)$ des Senderprozesses $i$ beigefügt. Wenn ein weiterer Prozess $j$ diese Nachricht erhält, so wird der aktuelle Lamport-Zeitstempel $t_l(j)$ von Prozess $j$ wie folgt neu berechnet:
-
-\begin{equation*}
- t_l(j) := 1 + max(t_l(j), t_l(i))
-\end{equation*}
-
-Es wird also stets die größere Lamportzeit vom Sender- und Empfängerprozess verwendet und anschließend um \textit{1} inkrementiert. Nach Ablauf der Berkeley-Simulation hat P1 \textit{(16)}, P2 (\textit{14}) und P3 (\textit{15}) als Lamport-Zeitstempel abgespeichert.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-berkeley-vektor}}
- \caption{Vektor-Zeitstempel}
- \label{fig:Vektorzeit}
-\end{figure}
-
-Mit aktivem Vektorzeit-Schalter werden alle Vektor-Zeitstempel angezeigt (s. Abb. \ref{fig:Vektorzeit}.). Wie beim Lamport-Zeitstempel wird auch hier jeder Nachricht der aktuelle Vektor-Zeitstempel des Senderprozesses beigefügt. Bei $n$ beteiligten Prozessen hat der Vektor-Zeitstempel $v$ die Größe $n$. Somit gibt es für jeden beteiligten Prozess $i$ einen eigenen Index $i$. Mit $v(i)$ kann jeder Prozess auf seinen lokalen Eintrag zugreifen. Wenn $v$ der Vektor-Zeitstempel des Empfängerprozesses $j$ ist und $w$ der Vektor-Zeitstempel des Senderprozesses ist, dann wird der neue lokale Vektor-Zeitstempel vom Prozess $j$ wie folgt neu berechnet:
-
-\textbf{Pseudo-Code}
-
-\begin{code}
-for (i := 0; i < n; i++) {
- if (i = j) {
- v(i)++;
- } else if (v(i) < w(i)) {
- v(i) := w(i);
- }
-}
-\end{code}
-
-Standardmäßig wird der Vektor-Zeitstempel nur inkrementiert, wenn eine Nachricht verschickt- oder erhalten wird. Bei beiden Fällen inkrementiert der Sender- und Empfängerprozess jeweils seinen eigenen Index im Vektor-Zeitstempel um \textit{1}. Beim Empfang einer Nachricht wird anschließend der lokale Vektor-Zeitstempel mit dem des Senderprozesses verglichen und für alle Indizes stets der größere Wert in den lokalen Vektor-Zeitstempel übernommen.
-
-Im Beispiel (vgl. Abbildung \ref{fig:Vektorzeit}.) hat P1 \textit{(8,10,6)}, P2 \textit{(6,10,6)}. und P3 \textit{(6,10,8)} als Vektor-Zeitstempel abgespeichert.
-
-Wenn während einer Simulation Prozesse entfernt- oder neue Prozesse hinzugefügt werden, so passt sich die Größe der Vektor-Zeitstempel aller anderen Prozesse automatisch der Gesamtzahl der Prozesse an.
-
-Wie bereits beschrieben (s. Kap. 2.4.2.) gibt es in den Simulationseinstellungen die boolschen Variablen ``Lamportzeiten betreffen alle Ereignisse'' und ``Vektorzeiten betreffen alle Ereignisse'', die standardmäßig auf \textit{false} gesetzt sind. Mit \textit{true} werden alle Ereignisse, und nicht nur der Empfang oder das Versenden einer Nachricht, berücksichtigt. Für eine weitere Betrachtung der Lamport- sowie Vektor-Zeitstempel siehe \cite{Vorlesung} oder \cite{Tanenbaum}.
-
-\subsection{Simulation langsamer Verbindungen \small{\textit{(slow-connection.dat)}}}
-
-Mit dem Simulator lassen sich auch langsame Verbindungen zu einem bestimmten Prozess simulieren. Für die Demonstration wird das Beispiel aus Kapitel 3.5. wieder aufgegriffen, wo das Protokoll zur internen Synchronisation (durch P1) mit der Christians-Methode (durch P3) parallel simuliert wurden. P2 stellt den Server beider Protokolle zur Verfügung. In diesem Szenario soll P3 eine schlechte Netzwerkverbindung besitzen, so dass Nachrichten von- und an P3 stets eine längere Übertragungszeit benötigen.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=10cm]{images/ss-protokoll-time-sync-2-long-transfer}}
- \caption{Simulation einer langsamen Verbindung}
- \label{fig:TimeSync2LongTransferProto}
-\end{figure}
-
-Die Ereignisse sind so wie bereits in Tabelle \ref{tb:InterneSync2Tasks}. dargestellt wurde programmiert. In den Simulationseinstellungen ist hier die Einstellung ``Mittelwerte der Übertragungszeiten bilden'' aktiviert. In den Prozesseinstellungen von P3 wurde die ``Minimale Übertragungszeit'' auf \textit{2000ms} und die ``Maximale Übertragungszeit'' auf \textit{8000ms} gestellt. P1 und P2 behalten als Standardeinstellungen für die minimale und maximale Übertragungszeiten die Werte \textit{500ms} und \textit{2000ms}, die Simulationsdauer betr\"{a}gt nun \textit{20000ms}.
-
-Als Folge (s. Abb. \ref{fig:TimeSync2LongTransferProto}.) benötigen Nachrichten, die von- und an P3 verschickt werden, für eine Übertragung immer mehr Zeit. Bevor P3 eine Antwort auf seine vorherige Anfrage bekommt, verschickt er eine erneute Anfrage. Da P3 die Serverantworten immer stets seiner letzten verschickten Anfrage zuordnet, berechnet er alle RTTs inkorrekt und seine lokale Zeit wird dadurch bei jedem Durchgang erneut falsch bestimmt. Die Berechnungsformeln der Übertragungszeiten wurde bereits in Kapitel 2.4.3. bei den Prozesseinstellungen behandelt. Konkret bedeutet dies hier für die Übertragungszeiten alle Nachrichten von- und an P3 jeweils:
-
-\begin{equation*}
- \frac{1}{2} (rand(500, 2000) + rand(2000, 8000)) = \frac{1}{2} rand(2500, 10000) = rand(1250, 5000) ms
-\end{equation*}
-
-In dem Beispiel in Abbildung \ref{fig:TimeSync2LongTransferProto}. ist die lokale Prozesszeit von P1 bis auf \textit{20000 - 21446 = - 1446ms} synchronisiert, w\"{a}hrend die Prozesszeit von P3 ganze \textit{20000 - 16557 = 3443ms} falsch geht.
diff --git a/LaTeX/chapters/simulator.tex b/LaTeX/chapters/simulator.tex deleted file mode 100644 index c3e9a84..0000000 --- a/LaTeX/chapters/simulator.tex +++ /dev/null @@ -1,370 +0,0 @@ -\chapter{Grafische Benutzeroberfläche (GUI)}
-
-\section{Einfacher Modus}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=12cm]{images/ss-neues-fenster}}
- \caption{Der Simulator nach dem ersten Starten}
- \label{fig:NeuesFenster}
-\end{figure}
-
-Der Simulator ben\"{o}tigt die JRE 6.0 (1.6) und lässt sich mit dem Befehl \textit{java -jar VS-Sim.jar} starten. Der Simulator präsentiert sich danach so wie in Abbildung \ref{fig:NeuesFenster}. zu sehen ist. Für die Erstellung einer neuen Simulation wird im Menü ``Datei'' (s. Abb. \ref{fig:DateiMenue}.) der Punkt ``Neue Simulation'' ausgewählt, wo anschließend das Einstellungsfenster für die neue Simulation erscheint. Auf die einzelnen Optionen wird später genauer eingegangen und es werden nun nur die Standardeinstellungen übernommen. Die GUI mit einer frischen Simulation sieht aus wie in Abbildung \ref{fig:NeuErstellteSimulation}.
-
-Standardm\"{a}ßig wird der Simulator im ``einfachen Modus'' gestartet. Daneben gibt es noch einen ``Expertenmodus'', auf welchen sp\"{a}ter eingegangen wird.
-
-\subsubsection{Die Menüzeile}
-
-Im Datei-Menü (s. Abb. \ref{fig:DateiMenue}.) lassen sich neue Simulationen erstellen oder die aktuell geöffnete Simulation schließen. Neue Simulationen öffnen sich standardmäßig in einem neuen Tab. Es können allerdings auch neue Simulationsfenster, die wiederum eigene Tabs besitzen, geöffnet oder geschlossen werden. In jedem Tab befindet sich eine, von den anderen vollständig unabhängige Simulation. Es können somit beliebig viele Simulationen parallel ausgeführt werden. Die Menüeinträge ``Öffnen'', ``Speichern'' und ``Speichern unter'' dienen für das Laden und Speichern von Simulationen.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=6.5cm]{images/ss-datei-menu}}
- \caption{Datei-Menü}
- \label{fig:DateiMenue}
-\end{figure}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=12cm]{images/ss-neue-simulation}}
- \caption{Eine neue Simulation}
- \label{fig:NeuErstellteSimulation}
-\end{figure}
-
-Über das Editieren-Menü gelangt der Anwender zu den Simulationseinstellungen, worauf später genauer eingegangen wird. In diesem Menü werden auch alle beteiligten Prozesse zum Editieren aufgelistet. Wählt der Anwender dort einen Prozess aus, dann öffnet sich der dazugehörige Prozesseditor. Auf diesen wird ebenso später genauer eingegangen. Das Simulator-Menü bietet die selben Optionen wie die Toolbar, welche im nächsten Teilkapitel beschrieben wird, an.
-
-Einige Menüunterpunkte sind erst erreichbar, wenn im aktuellen Fenster bereits eine Simulation erstellt oder geladen wurde.
-
-\subsubsection{Die Toolbar}
-
-Oben links im Simulator befindet sich die Toolbar (s. Abb. \ref{fig:Toolbar}.). Die Toolbar enthält die Funktionen die vom Anwender am häufigsten benötigt werden.
-
-Die Toolbar bietet vier verschiedene Funktionen an:
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=5cm]{images/ss-neue-simulation-toolbar}}
- \caption{Die Menüzeile inklusive Toolbar}
- \label{fig:Toolbar}
-\end{figure}
-
-\begin{itemize}
- %\setlength{\itemsep}{-1mm}
- \item Zurücksetzen der Simulation; kann nur betätigt werden, wenn die Simulation pausiert wurde oder wenn die Simulation abgelaufen ist.
- \item Wiederholen der Simulation; kann nicht betätigt werden, wenn die Simulation noch nicht gestartet wurde.
- \item Pausieren der Simulation; kann nur betätigt werden, wenn die Simulation derzeit läuft.
- \item Starten der Simulation; kann nur betätigt werden, wenn die Simulation derzeit nicht läuft und noch nicht abgelaufen ist.
-\end{itemize}
-
-\newpage
-\subsubsection{Die Visualisierung}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=12cm]{images/ss-visualisierung}}
- \caption{Visualisierung einer noch nicht gestarteten Simulation}
- \label{fig:Visualisierung}
-\end{figure}
-
-Mittig rechts befindet sich die grafische Simulationsvisualisierung. Die X-Achse gibt die Zeit in Millisekunden an und auf der Y-Achse sind alle beteiligten Prozesse aufgeführt. Die Demo-Simulation endet nach genau 15 Sekunden. In Abbildung \ref{fig:Visualisierung}. sind 3 Prozesse (mit den PIDs 1, 2 und 3) dargestellt, die jeweils einen eigenen horizontalen schwarzen Balken besitzen. Auf diesen Prozessbalken kann der Anwender die jeweilige lokale Prozesszeit ablesen. Die vertikale rote Linie stellt die globale Simulationszeit dar.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=8.8cm]{images/ss-rechtsklick-prozessbalken}}
- \caption{Rechtsklick auf einen Prozessbalken}
- \label{fig:RechtsklickProzessbalken}
-\end{figure}
-
-Die Prozessbalken dienen auch für Start- und Zielpunkte von Nachrichten. Wenn beispielsweise Prozess 1 eine Nachricht an Prozess 2 verschickt, so wird eine Linie vom einen Prozessbalken zum anderen gezeichnet. Nachrichten, die ein Prozess an sich selbst verschicken, werden nicht visualisiert. Sie werden aber im Logfenster (mehr dazu später) protokolliert.
-
-Eine andere Möglichkeit einen Prozesseditor aufzurufen ist ein Linksklick auf den zum Prozess gehörigen Prozessbalken. Ein Rechtsklick hingegen öffnet ein Popup-Fenster mit weiteren Auswahlmöglichkeiten (s. Abb. \ref{fig:RechtsklickProzessbalken}.). Ein Prozess kann über das Popup-Menü nur während einer laufenden Simulation zu einem Absturz oder einer Wiederbelebung bewegt werden.
-
-Generell kann die Anzahl der Prozesse nach Belieben variieren. Die Dauer der Simulation beträgt mindestens \textit{5} und höchstens \textit{120} Sekunden. Die Simulation endet erst, wenn sie die globale Zeit die angegebene Simulationsendzeit (hier \textit{15} Sekunden) erreicht hat, und nicht, wenn eine lokale Prozesszeit diese Endzeit erreicht.
-
-\subsubsection{Farbliche Differenzierung}
-
-
-Farben helfen dabei die Vorgänge einer Simulation besser zu deuten. Standardmäßig werden die Prozesse (Prozessbalken) und Nachrichten mit den Farben, wie in Tabelle \ref{tb:Farben}. aufgelistet, dargestellt. Dies sind lediglich die Standardfarben, welche über die Einstellungen geändert werden können.
-
-\begin{table}
- \fbox{
- \begin{tabular}{c|l}
- \textbf{Prozessfarbe} & \textbf{Bedeutung} \\
- \hline
- Schwarz & Die Simulation läuft derzeit nicht\\
- \hline
- Orange & Die Maus befindet sich über den Prozessbalken\\
- \hline
- Rot & Der Prozess ist abgestürzt\\
- & \\
- \textbf{Nachrichtenfarbe} & \textbf{Bedeutung} \\
- \hline
- Grün & Die Nachricht ist noch unterwegs und hat das Ziel noch nicht erreicht\\
- \hline
- Blau & Die Nachricht hat das Ziel erfolgreich erreicht\\
- \hline
- Rot & Die Nachricht ging verloren\\
- \end{tabular}\\
- }
- \caption{Farbliche Differenzierung von Prozessen und Nachrichten}
- \label{tb:Farben}
-\end{table}
-
-\newpage
-\subsubsection{Die Sidebar}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=9cm]{images/ss-sidebar}}
- \caption{Die Sidebar mit leerem Ereigniseditor}
- \label{fig:Sidebar}
-\end{figure}
-
-Mit Hilfe der Sidebar lassen sich Prozessereignisse programmieren. Oben in Abbildung \ref{fig:Sidebar}. ist der zu verwaltende Prozess selektiert (hier mit der PID 1). In dieser Prozessauswahl gibt es auch die Möglichkeit ``Alle Prozesse'' auszuwählen, womit alle programmierten Ereignisse aller Prozesse gleichzeitig dargestellt werden. Unter ``Lokale Ereignisse'' versteht man diejenigen Ereignisse, die auftreten, wenn eine bestimmte lokale Zeit des dazugehörigen Prozesses eingetreten ist. Die darunter liegende Ereignistabelle listet alle programmierten Ereignisse (hier noch keine vorhanden) mitsamt Eintrittszeiten sowie den PIDs auf.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=9cm]{images/ss-sidebar-mit-ereignissen}}
- \caption{Der Ereigniseditor mit 3 programmierten Ereignissen}
- \label{fig:SidebarMitEreignissen}
-\end{figure}
-
-Für die Erstellung eines neuen Ereignisses kann der Anwender entweder mit einem Rechtsklick auf einen Prozessbalken (s. Abb. \ref{fig:RechtsklickProzessbalken}.) klicken und dort ``Lokales Ereignis einfügen'' wählen, oder unterhalb der Ereignistabelle ein Ereignis auswählen (s. Abb. \ref{fig:Ereignisauswahl}.), im darunter liegenden Textfeld die Ereigniseintrittszeit eintragen und auf ``Übernehmen'' gehen. Beispielsweise wurden in Abbildung \ref{fig:SidebarMitEreignissen}. drei Ereignisse hinzugefügt: Absturz nach \textit{123ms}, Wiederbelebung nach \textit{321ms} und erneuter Absturz nach \textit{3000ms} des Prozesses mit der ID 1.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=9cm]{images/ss-ereignisauswahl}}
- \caption{Die Ereignisauswahl via Sidebar}
- \label{fig:Ereignisauswahl}
-\end{figure}
-
-Mit einem Rechtsklick auf den Ereigniseditor lassen sich alle selektierten Ereignisse entweder kopieren oder löschen. Mit Hilfe der Strg-Taste können auch mehrere Ereignisse gleichzeitig markiert werden. Die Einträge der Spalten für die Zeit und der PID lassen sich nachträglich editieren. Somit besteht eine komfortable Möglichkeit bereits programmierte Ereignisse auf eine andere Zeit zu verschieben oder einen anderen Prozess zuzuweisen. Allerdings sollte der Anwender darauf achten, dass er nach dem ändern der Ereigniseintrittszeit die Enter-Taste betätigt, da sonst die Änderung unwirksam ist.
-
-In der Sidebar gibt es neben dem Ereignis-Tab einen weiteren Tab ``Variablen''. Hinter diesem Tab verbirgt sich der Prozesseditor des aktuell ausgewählten Prozesses (s. Abb. \ref{fig:NeueSimulationVariablen}. links). Dort können alle Variablen des Prozesses editiert werden und ist somit eine weitere Möglichkeit einen Prozesseditor aufzurufen.
-
-\subsubsection{Das Logfenster}
-
-Das Logfenster (s. Abb. \ref{fig:NeuErstellteSimulation}., unten) protokolliert in chronologischer Reihenfolge alle eingetroffenen Ereignisse. In Abbildung \ref{fig:Logfenster}. ist das Logfenster nach Erstellung der Demo-Simulation zu sehen, an welcher 3 Prozesse beteiligt sind. Am Anfang eines Logeintrages wird stets die globale Zeit in Millisekunden protokolliert. Bei jedem Prozess werden ebenso seine lokalen Zeiten sowie die Lamport- und die Vektor-Zeitstempel aufgeführt. Hinter den Zeitangaben werden weitere Angaben, wie beispielsweise welche Nachricht mit welchem Inhalt verschickt wurde und welchem Protokoll sie angehört, gemacht. Dies wird später noch anhand von Beispielen demonstriert.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=16.5cm]{images/ss-loggfenster}}
- \caption{Das Logfenster}
- \label{fig:Logfenster}
-\end{figure}
-
-Mit dem Deaktivieren des Logging-Schalters lässt sich das Loggen von Nachrichten temporär ausstellen. Mit deaktiviertem Loggen werden keine neuen Nachrichten mehr ins Logfenster geschrieben. Nach Reaktivieren des Schalters werden alle ausgelassenen Nachrichten nachträglich in das Fenster geschrieben. Ein deaktiviertes Loggen kann zu verbessertem Leistungsverhalten des Simulators führen. Dieser Umstand ist der sehr langsamen Java-Implementierung der JTextArea-Klasse zu verdanken, die Updates nur sehr träge durchführt (s. \cite{Swing}).
-
-Über den Schalter ``Expertenmodus'' wird der Expertenmodus aktiviert, bzw. deaktiviert.
-
-\section{Expertenmodus}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=12cm]{images/ss-simulation-expertenmodus}}
- \caption{Der Simulator im Expertenmodus}
- \label{fig:SimulationExpertenmodus}
-\end{figure}
-
-Der Simulator kann in zwei verschiedenen Modi betrieben werden. Es gibt einen einfachen und einen Expertenmodus. Der Simulator startet standardmäßig im einfachen Modus, so dass sich der Anwender nicht mit der vollen Funktionalität des Simulators auf einmal auseinandersetzen muss. Der einfache Modus ist übersichtlicher, bietet jedoch weniger Funktionen an. Der Expertenmodus eignet sich mehr für erfahrene Anwender und bietet dementsprechend auch mehr Flexibilität. Der Expertenmodus kann über den gleichnamigen Schalter unterhalb des Logfensters oder über die Simulationseinstellungen aktiviert oder deaktiviert werden. In Abbildung \ref{fig:SimulationExpertenmodus}. ist der Simulator im Expertenmodus zu sehen. Wenn der Expertenmodus mit dem einfachen Modus verglichen wird, so fallen einige Unterschiede auf:
-
-\subsubsection{Neue Funktionen in der Sidebar}
-
-Der erste Unterschied ist in der Sidebar erkennbar (s. Abb. \ref{fig:SidebarExpertenmodus}.). Dort sind nun, zusätzlich zu den lokalen Ereignissen, auch globale Ereignisse editierbar. Wie bereits erwähnt sind unter lokale Ereignisse diejenigen Ereignisse zu verstehen, die auftreten, wenn eine bestimmte lokale Zeit des dazugehörigen Prozesses eingetreten ist. Globale Ereignisse hingegen sind diejenigen Ereignisse, die auftreten, wenn eine bestimmte globale Zeit eingetreten ist. Ein globales Ereignis nimmt die globale Simulationszeit und ein lokales Ereignis die lokale Prozesszeit als Eintrittskriterium. Globale Ereignisse machen somit nur einen Unterschied, wenn sich die lokalen Prozesszeiten von der globalen Zeit unterscheiden.
-
-Des Weiteren kann der Anwender bei der Programmierung eines neuen Ereignisses direkt die dazugehörige PID selektieren. Im einfachen Modus wurde hier immer standardmäßig die PID des aktuell (in der obersten Combo-Box) ausgewählten Prozesses verwendet (hier mit PID 1).
-
-\subsubsection{Lamportzeit-, Vektorzeit- und Anti-Aliasing Schalter}
-
-Weitere Unterschiede machen sich unterhalb des Logfensters bemerkbar. Dort gibt es unter anderem zwei neue Schalter ``Lamportzeit'' und ``Vektorzeit''. Aktiviert der Anwender einen dieser beiden Schalter, so werden die Lamport- bzw. die Vektor-Zeitstempel in der Visualisierung dargestellt. Damit die Übersichtlichkeit nicht leidet, kann der Anwender nur jeweils einen dieser beiden Schalter zur gleichen Zeit aktiviert haben.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=9cm]{images/ss-sidebar-expertenmodus}}
- \caption{Die Sidebar im Expertenmodus}
- \label{fig:SidebarExpertenmodus}
-\end{figure}
-
-Der Anti-Aliasing-Schalter ermöglicht dem Anwender Anti-Aliasing zu aktivieren bzw. zu deaktivieren. Mit Anti-Aliasing werden alle Grafiken der Visualisierung gerundet dargestellt (s. \cite{Games}). Aus Performance-Gründen ist Anti-Aliasing standardmäßig nicht aktiv.
-
-\subsubsection{Der Logfilter}
-
-Je komplexer eine Simulation wird, desto unübersichtlicher werden die Einträge im Logfenster. Hier fällt es zunehmend schwerer die Übersicht aller Ereignisse zu behalten. Um dem entgegenzuwirken gibt es im Expertenmodus einen Logfilter, welcher es ermöglicht nur die wesentlichen Daten aus den Logs zu filtern.
-
-Der Logfilter wird anhand des dazugehörigen Schalters ``Filter'' aktiviert und deaktiviert. In der dahinterliegenden Eingabezeile kann ein regulärer Ausdruck in Java-Syntax, angegeben werden. Die Verwendung regul\"{a}rer Ausdr\"{u}cke mittels Java wird in \cite{Regexp} behandelt. Beispielsweise werden mit ``\textit{PID: (1|2)}'' nur Logzeilen angezeigt, die entweder ``\textit{PID: 1}'' oder ``\textit{PID: 2}'' beinhalten. Alle anderen Zeilen, die z.B. nur ``\textit{PID: 3}'' beinhalten, werden dabei nicht angezeigt. Mit Logfilter werden nur die Logzeilen angezeigt, auf die der angegebene reguläre Ausdruck passt. Der Logfilter kann auch nachträglich aktiviert werden, da bereits protokollierte Ereignisse nach jeder Filteränderung erneut gefiltert werden.
-
-Der Logfilter kann auch während einer laufenden Simulation verwendet werden. Bei Filterdeaktivierung werden alle Nachrichten wieder dargestellt. Lognachrichten, die aufgrund des Filters noch nie angezeigt wurden, werden dann nachträglich angezeigt.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics[width=12cm]{images/ss-neue-simulation-variablen}}
- \caption{Der Prozesseditor in der Sidebar}
- \label{fig:NeueSimulationVariablen}
-\end{figure}
-
-\section{Ereignisse}
-
-Es wird zwischen zwei Haupttypen von Ereignissen unterschieden: Programmierbare Ereignisse und nicht programmierbare Ereignisse. Programmierbare Ereignisse lassen sich im Ereigniseditor programmieren und editieren und deren Eintrittszeiten hängen von den lokalen Prozessuhren oder der globalen Uhr ab. Nicht programmierbare Ereignisse lassen sich hingegen nicht im Ereigniseditor programmieren und treten nicht wegen einer bestimmten Uhrzeit ein, sondern aufgrund anderer Gegebenheiten wie z.B. das Eintreffen einer Nachricht oder das Ausführen einer Aktion aufgrund eines Weckers (mehr dazu sp\"{a}ter).
-
-\subsubsection{Prozessabsturz- und Wiederbelebung (programmierbar)}
-
-Die beiden einfachsten Ereignisse sind ``Prozessabsturz'' sowie ``Prozesswiederbelebung''. Wenn ein Prozess abgestürzt ist, so wird sein Prozessbalken in rot dargestellt. Ein abgestürzter Prozess kann keine weiteren Ereignisse mehr verarbeiten und wenn bei ihm eine Nachricht eintrifft, dann geht sie verloren. Die einzige Ausnahme bietet ein Wiederbelebungsereignis. Ein abgestürzter Prozess kann nichts, außer wiederbelebt werden. Während eines Prozessabsturzes läuft die lokale Prozessuhr, abgesehen von den Lamport- und Vektor-Zeitstempel, normal weiter. Das heißt, es besteht die Möglichkeit, dass ein Prozess einige seiner Ereignisse gar nicht ausführt, da er zu den Ereigniseintrittszeiten abgestürzt ist.
-
-\subsubsection{Aktivierung und Deaktivierung von Protokollen sowie Starten von Anfragen (programmierbar)}
-Es ist bereits bekannt, dass ein Prozess mehrere Protokolle client- und auch serverseitig unterstützen kann. Welches Protokoll von einem Prozess unterstützt wird, kann der Anwender anhand von Protokollaktivierungs- und Protokolldeaktivierungsereignissen konfigurieren. Somit besteht die Möglichkeit, dass ein gegebener Prozess ein bestimmtes Protokoll erst zu einem bestimmten Zeitpunkt unterstützt und ggf. ein anderes Protokoll ablöst. Jedes Protokoll kann entweder server- oder clientseitig aktiviert bzw. deaktiviert werden. Der Anwender hat somit die Auswahl zwischen fünf verschiedenen Protokollereignistypen:
-
-\begin{itemize}
- \item Aktivierung des Clients eines gegebenen Protokolls
- \item Aktivierung des Servers eines gegebenen Protokolls
- \item Deaktivierung des Clients eines gegebenen Protokolls
- \item Deaktivierung des Servers eines gegebenen Protokolls
- \item Starten einer Client/Server-Anfrage eines gegebenen Protokolls
-\end{itemize}
-
-Ob sich das Ereignis für das Starten einer Anfrage auf einen Client oder einen Server bezieht, hängt vom verwendeten Protokoll ab. Es gibt Protokolle, wo der Client die Anfragen starten muss, und es gibt Protokolle, wo der Server diese Aufgabe übernimmt. Beispielsweise startet bei dem ``Ping-Pong Protokoll'' der Client und bei dem ``Commit-Protokollen'' der Server immer die Anfragen. Es gibt kein Protokoll, wo der Client und der Server jeweils Anfragen starten können.
-
-\subsubsection{Nachrichtenempfang sowie Antwortnachrichten (nicht-programmierbar)}
-
-Nachdem ein Prozess eine Nachricht empfängt wird zuerst überprüft, ob er das dazugehörige Protokoll unterstützt. Wenn der Prozess das Protokoll unterstützt, wird geschaut, ob es sich um eine Client- oder eine Servernachricht handelt. Wenn es sich um eine Clientnachricht handelt, so muss der Empfängerprozess das Protokoll serverseitig unterstützen und virce versa. Wenn alles passt, dann führt der Empfängerprozess die vom Protokoll definierten Aktionen aus. In der Regel berechnet der Prozess einen bestimmten Wert und schickt ihn über eine Antwortnachricht zurück. Es können aber auch beliebig andere Aktionen ausgeführt werden. Welche dies sind hängt vom Protokoll ab.
-
-\subsubsection{Callback-Ereignisse (nicht-programmierbar)}
-
-Ein Callback-Ereignis kann von einem Protokoll ausgelöst werden. Das Protokoll setzt einen Wecker, der angibt zur welcher lokalen Uhrzeit eine weitere Aktion ausgeführt werden soll. Zum Beispiel lassen sich hiermit Timeouts realisieren: Wenn ein Protokoll eine Antwort erwartet, diese aber nicht eintrifft, dann kann nach einer bestimmten Zeit eine Anfrage erneut verschickt werden! Es können beliebig viele Callback-Ereignisse definiert werden. Wenn sie noch nicht ausgeführt wurden und aufgrund eines anderen Ereignisses nicht mehr benötigt werden, dann können sie vom Protokoll wieder nachträglich entfernt werden. Wenn ein Callback-Ereignis ausgeführt wird, dann kann es sich selbst wieder für eine weitere Ausführung erneut planen. So lassen sich periodisch wieder-eintreffende Ereignisse realisieren. Beispielsweise verwenden die sog. Commit-Protokolle (s. Kap. 3.3.7, 3.3.8) Callback-Ereignisse, indem solange Anfragen verschickt werden, bis alle benötigten Antworten vorliegen.
-
-\subsubsection{Zufallsereignisse (nicht-programmierbar)}
-
-Die Eintrittszeit eines Zufallsereignisses wird vom Simulator zufällig gewählt. Es besteht lediglich die Möglichkeit die Wahrscheinlichkeit, dass das Ereignis überhaupt eintritt, einzustellen. Ein Beispiel ist ein zufälliger Prozessabsturz, dessen Wahrscheinlichkeit unter den Prozessvariablen konfiguriert werden kann (s. Kapitel 2.4.3.).
-
-
-\section{Einstellungen}
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{l|l}
- \textbf{Typ} & \textbf{Beschreibung}\\
- \hline
- \textit{Boolean} & Boolescher Wert, z.B. \textit{true} oder \textit{false}\\
- \textit{Color} & Java-Farbobjekt\\
- \textit{Float} & 32-Bit Fließkommazahl\\
- \textit{Integer[]} & Vektor aus 32-Bit Integer\\
- \textit{Integer} & 32-Bit Integer\\
- \textit{Long} & 64-Bit Long\\
- \textit{String} & Java-Stringobjekt\\
- \end{tabular}
- }
- \caption{Verfügbare Datentypen für editierbare Variablen}
- \label{tb:VariablenDatentypen}
-\end{table}
-
-
-In diesem Abschnitt wird genauer auf die möglichen Konfigurationsmöglichkeiten eingegangen. Zunächst gibt es globale Simulationseinstellungen. Diese beinhalten Variablen die die gesamte Simulation betreffen. Zudem hat jeder Prozess seine eigenen lokale Einstellungen. Darüber hinaus kann jedes Protokoll (Client- sowie Serverseite) für jeden Prozess separat eingestellt werden.
-
-\subsection{Variablendatentypen}
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics{images/ss-simulationseinstellungen}}
- \caption{Das Fenster zu den Simulationseinstellungen}
- \label{fig:Simulationseinstellungen}
-\end{figure}
-
-
-Der Simulator unterscheidet zwischen mehreren Datentypen, in denen die einstellbaren Variablen vorliegen können (s. Tabelle \ref{tb:VariablenDatentypen}.). Jede Variable besitzt einen Namen, einen Wert und eine optionale Beschreibung. Wenn eine Variablenbeschreibung vorhanden ist, so wird sie anstelle des Variablennamen in einem Editor angezeigt. Der Variablenname wird vom Simulator lediglich für die interne Verwendung benötigt. Im folgenden bedeutet \textit{Typ: varname = wert}, dass die Variable vom Typ \textit{Typ} ist, der interne Variablenname \textit{varname} lautet, und standardmäßig den Wert \textit{wert} zugewiesen hat. Vom Anwender lassen sich lediglich die Variablenwerte, jedoch nicht die Variablentypen, Variablennamen und Beschreibungen ändern.
-
-\subsection{Simulationseinstellungen}
-
-
-Beim Erstellen einer neuen Simulation erscheint zunächst das dazugehörige Einstellungsfenster (s. Abb. \ref{fig:Simulationseinstellungen}.). In der Regel reicht es, wenn der Anwender hier, bis auf die Anzahl beteiligter Prozesse, die Standardwerte übernimmt. Es besteht auch die Möglichkeit die Einstellungen nachträglich zu editieren, indem das Einstellungsfenster via ``Editieren $\rightarrow$ Einstellungen'' erneut aufgerufen wird.
-
-Im Folgenden werden alle in den Simulationseinstellungen verfügbaren Variablen beschrieben. Die Klammern geben die Typen, Namen und die Standardwerte an, in denen die Variablen vorliegen.
-
-\begin{figure}[h]
- \centering
- \fbox{\includegraphics{images/ss-simulationseinstellungen-experten}}
- \caption{Weitere Simulationseinstellungen im Expertenmodus}
- \label{fig:SimulationseinstellungenExperten}
-\end{figure}
-
-
-\begin{itemize}
- \item \textbf{Prozesse empfangen eigene Nachrichten} \textit{(Boolean: sim.message.own.recv = false)}: Standardmäßig können Prozesse keine Nachrichten empfangen, die sie selbst verschickt haben. Dies trägt zur Übersichtlichkeit der Simulation bei. Wenn diese Variable jedoch auf \textit{true} gesetzt wird, dann kann ein Prozess auch selbst verschickte Nachrichten empfangen und auf diese ebenso antworten. Die Zeit für das Versenden und Empfangen einer Nachricht an sich selbst beträgt jedoch stets \textit{0ms}. Diese Variable sollte mit Vorsicht verwendet werden, da bedingt durch den \textit{0ms} Endlosschleifen entstehen können.
- \item \textbf{Mittelwerte der Nachrichtenverlustwahrscheinlichkeiten bilden} \textit{(Boolean: sim.message.prob.mean = true)}: Jede Nachricht, die verschickt wird, hat, je nach Einstellungen, eine vom verschickenden Prozess abhängige zufällige Verlustwahrscheinlichkeit. Wenn diese Option aktiviert ist, wird der Mittelwert aus den Verlustwahrscheinlichkeiten des Senders- und Empfängerprozesses gebildet. Ansonsten wird die Verlustwahrscheinlichkeit, die beim Senderprozesses eingestellt wurde, verwendet.
- \item \textbf{Mittelwerte der Übertragungszeiten bilden} \textit{(Boolean: sim.message.sendingtime.mean = true)}: Jede Nachricht, die verschickt wird, hat, je nach Einstellungen, eine vom verschickenden Prozess abhängige zufällige Übertragungszeit bis sie ihr Ziel erreicht (siehe Prozesseinstellungen später). Wenn diese Option aktiviert ist, wird der Mittelwert vom Sender- und Empfängerprozess gebildet. Ansonsten wird die Übertragungszeit, die beim Senderprozesses angegeben wurde, verwendet.
- \item \textbf{Nur relevante Nachrichten anzeigen} \textit{(Boolean: sim.messages.relevant = true)}: Wenn nur alle relevanten Nachrichten angezeigt werden, dann werden Nachrichten an einen Prozess die er selbst nicht verarbeiten kann nicht angezeigt, da er das dazugehörige Protokoll nicht unterstützt. Dadurch wird die \"{U}bersichtlichkeit verbessert.
- \item \textbf{Expertenmodus aktivieren} \textit{(Boolean: sim.mode.expert = false)}: Hier lässt sich der Expertenmodus aktivieren und deaktivieren. Alternativ kann dies über den gleichnamigen Schalter unterhalb des Logfensters geschehen.
- \item \textbf{Simulation periodisch wiederholen} \textit{(Boolean: sim.periodic = false)}: Wenn diese Variable auf \textit{true} gesetzt ist, dann wird die Simulation jedes Mal nach Ablauf automatisch neu gestartet.
- \item \textbf{Lamportzeiten betreffen alle Ereignisse} \textit{(Boolean: sim.update.lamporttime.all = false)}: Wenn diese Variable auf \textit{true} gesetzt ist, dann werden bei jedem Ereignis alle Lamport-Zeitstempel aller Prozesse inkrementiert. Bei einem Wert \textit{false} werden die Lamport-Zeitstempel jeweils nur inkrementiert, wenn eine Nachricht empfangen oder verschickt wurde.
- \item \textbf{Vektorzeiten betreffen alle Ereignisse} \textit{(Boolean: sim.update.vectortime.all = false)}: Wenn diese Variable auf \textit{true} gesetzt ist, dann werden bei jedem Ereignis alle Vektor-Zeitstempel aller Prozesse inkrementiert. Bei einem Wert \textit{false} werden die Vektor-Zeitstempel jeweils nur inkrementiert, wenn eine Nachricht empfangen oder verschickt wurde.
- \item \textbf{Abspielgeschwindigkeit der Simulation} \textit{(Float: sim.clock.speed = 0.5)}: Gibt den Faktor der Simulationsabspielgeschindigkeit an. Wenn als Faktor \textit{1} gewählt wird, dann dauert eine Sekunde in einer Simulation so lange wie eine echte Zeitsekunde. Ein Wert von \textit{0.5} gibt somit an, dass die Simulation mit halber Echtzeitgschwindigkeit abgespielt werden soll.
- \item \textbf{Anzahl der Prozesse} \textit{(Integer: sim.process.num = 3)}: Gibt die Anzahl beteiligter Prozesse an. Der Anwender kann auch sp\"{a}ter w\"{a}hrend der Simulation mit einem Rechtsklick auf den Prozessbalken Prozesse aus der aktuellen Simulation entfernen oder weitere Prozesse hinzufügen.
- \item \textbf{Dauer der Simulation} \textit{(Integer: sim.seconds = 15)}: Gibt die Dauer der Simulation in Sekunden vor.
-\end{itemize}
-
-Alle weiteren Simulationeinstellungen unter ``Einstellungen für neue Prozesse'' sowie ``Nachrichteneinstellungen für neue Prozesse'' definieren das Verhalten des jeden neu erzeugten Prozesses.
-
-\begin{table}
- \centering
- \fbox{
- \begin{tabular}{l|l}
- \textbf{Schlüssel} & \textbf{Beschreibung}\\
- \hline
- \textit{col.background} & Hintergrundfarbe des Simulationsfensters\\
- \textit{col.message.arrived} & Nachrichtenfarbe wenn sie ihr Ziel erreicht hat\\
- \textit{col.message.lost} & Nachrichtenfarbe wenn sie verloren ging\\
- \textit{col.message.sending} & Nachrichtenfarbe wenn sie noch unterwegs ist\\
- \textbf{\textit{col.process.crashed}} & Prozessfarbe wenn er abgestürzt ist\\
- \textbf{\textit{col.process.default}} & Prozessfarbe wenn die Simulation aktuell nicht läuft und \\
- & der Prozess aktuell nicht abgestürzt ist \\
- \textbf{\textit{col.process.highlight}} & Prozessfarbe wenn die Maus über seinem Balken liegt\\
- \textit{col.process.line} & Farbe, in der die kleine ``Prozessfahne'' an der auch die \\
- & lokale Prozesszeit angegeben wird, dargestellt wird\\
- \textbf{\textit{col.process.running}} & Prozessfarbe wenn er nicht abgestürzt ist und die\\
- & Simulation aktuell läuft\\
- \textit{col.process.secondline} & Farbe der Sekunden-Zeitgitter\\
- \textit{col.process.sepline} & Farbe der globalen Zeitachse\\
- \textbf{\textit{col.process.stopped}} & Prozessfarbe wenn die Simulation pausiert wurde\\
- \end{tabular}
- }
- \caption{Farbeinstellungen}
- \label{tb:Farbeinstellungen}
-\end{table}
-
-\subsection{Prozess- und Protokolleinstellungen}
-
-Jeder Prozess besitzt folgende Variablen:
-
-\begin{itemize}
- \item \textbf{Uhrabweichung} \textit{(Float: process.clock.variance = 0.0)}: Gibt den Wert $t_v$ an, um den die lokale Prozessuhr $t$ abweicht. Wenn $t_n$ die neu verstrichene Zeit ist, dann wird die lokale Prozessuhr wie folgt neu berechnet:
-\begin{equation*}
- t := t + t_n * t_v
-\end{equation*}
- Der Wert \textit{0.0} besagt beispielsweise, dass die Uhr keine Abweichung hat und somit global-korrekt läuft. Ein Wert von \textit{1.0} hingegen bedeuten, dass die Uhr mit doppelter Geschwindigkeit l\"{a}uft. Ein Wert von \textit{-0.5} bedeutet, dass die lokale Prozessuhr mit halber globaler Geschwindigkeit fortschreitet. Es sind nur Werte > \textit{-1.0} erlaubt, da sonst die Prozessuhr rückwärts laufen könnte. Bei allen anderen Werten wird die Einstellung wieder automatisch auf \textit{0.0} gesetzt. Der Simulator arbeitet intern mit Fließkommazahlen doppelter Genauigkeit arbeitet, so dass es es zu kleinen, jedoch vernachlässigbaren Rundungsfehlern kommen.
- \item \textbf{Prozessausfallwahrscheinlichkeit} \textit{(Integer: process.prob.crash = 0)}: Gibt eine Wahrscheinlichkeit in Prozent an, mit der der Prozess während der Simulation zufällig abstürzt. Die Wahrscheinlichkeit bezieht sich auf die komplette Simulationsdauer. Bei einer Einstellung von \textit{100} Prozent und der Simulationsdauer von \textit{15} Sekunden stürzt der Prozess auf jeden Fall zwischen \textit{0ms} und \textit{15000ms} ab. An welcher Stelle dies geschieht wird zufällig bestimmt. Wenn der Prozess nach seinem Absturz wiederbelebt wird, stürzt er nicht mehr ab. Dies gilt allerdings nicht, wenn die Prozesseinstellungen nach dem Zufallsabsturz erneut geändert und übernommen werden, da dann das Zufallsabstürzereignis erneut erstellt wird.
- \item \textbf{Lokale Zeit} \textit{(Long: process.localtime = 0)}: Gibt die lokale Prozesszeit in Millisekunden an.
- \item \textbf{Nachrichtenverlustwahrscheinlichkeit} \textit{(Integer: message.prob.crash = 0)}: Gibt eine Wahrscheinlichkeit in Prozent an, mit der eine vom aktuell ausgewählten Prozess verschickte Nachricht unterwegs verloren geht. An welcher Stelle die Nachricht zwischen dem Sende- und Empfängerprozess verloren geht wird zufällig bestimmt.
- \item \textbf{Maximale Übertragungszeit} \textit{(Long: message.sendingtime.max = 2000)}: Gibt die Dauer in Millisekunden an, die eine vom Prozess verschickte Nachricht maximal benötigt, um einen Empfängerprozess zu erreichen. Im weiteren Verlauf wird dieser Wert mit $t_{max}$ bezeichnet.
- \item \textbf{Minimale Übertragungszeit} \textit{(Long: message.sendingtime.min = 500)}: Gibt die Dauer in Millisekunden an, die eine vom Prozess verschickte Nachricht minimal benötigt, bis sie einen Empfängerprozess erreicht. Im weiteren Verlauf wird dieser Wert mit $t_{min}$ bezeichnet.
-
-Wenn die Übertragungszeiten von Nachrichten immer exakt die selbe Zeit in Anspruch nehmen sollen, dann müssen alle Prozesseinstellungen mit $t_{min} = t_{max}$ konfiguriert werden. Im Folgenden wird die globale Zeit mit $t_g$ bezeichnet. Ist die Simulationseinstellung ``Mittelwerte der Übertragungszeiten bilden'' nicht aktiv, dann wird die Ereigniseintrittszeit $t_e$ für den Empfang der Nachricht wie folgt berechnet:
-
-\begin{equation*}
- t_e := t_g + rand(t_{min}, t_{max})
-\end{equation*}
-
-Das heißt, dass die Nachricht nach einer zufälligen Zeit zwischen $t_{min}$ und $t_{max}$ beim Empfänger eintrifft. Für jeden Empfänger wird hierbei ein neuer Zufallswert gewählt. Für den Fall, dass die Einstellung ``Mittelwerte der Übertragungszeiten bilden'' aktiviert ist, und wenn $t'_{min}$ und $t'_{max}$ die beim Empfängerprozess eingestellten Werte entsprechen, dann wird die Nachrichtenempfangszeit wie folgt berechnet:
-
-\begin{equation*}
- t_e := t_g + \frac{1}{2} (rand(t_{min}, t_{max}) + rand(t'_{min}, t'_{max}))
-\end{equation*}
-
-Das bedeutet, dass der Mittelwert der Nachrichtenübertragungszeiten vom Sender- und Empfängerprozesses verwendet wird.
-
-\end{itemize}
-
-Im Prozesseditor lassen sich ebenfalls die Protokollvariablen editieren. Die Protokollvariablen werden in Kapitel 3. beschrieben.
-
-\subsection{Einstellungen im Expertenmodus}
-
-Im Expertenmodus lassen sich zusätzliche Variablen, wie Farbwerte und Fenstergrößen, editieren. Abbildung \ref{fig:SimulationseinstellungenExperten}. zeigt alle einstellbaren Farben. Die fett gedruckten Schlüssel in Tabelle \ref{tb:Farbeinstellungen}. sind mit Standardwerten für die neu zu erstellenden Prozesse belegt. Alle Werte sind in den Prozesseinstellungen des jeweiligen Prozesses individuell einstellbar.
-
diff --git a/LaTeX/chapters/titelseite.tex b/LaTeX/chapters/titelseite.tex deleted file mode 100644 index 4cbae22..0000000 --- a/LaTeX/chapters/titelseite.tex +++ /dev/null @@ -1,119 +0,0 @@ -% Diploma thesis template 2005 -% author: lukas.silberbauer(at)gmx.at -% based upon "Diplomarbeit mit LaTeX" by Tobias Erbsland -% published under the terms of -% ---------------------------------------------------------------------------- -% "THE BEER-WARE LICENSE": -% <lukas.silberbauer(at)gmx.at> wrote this file. As long as you retain this notice -% you can do whatever you want with this stuff. If we meet some day, and you think -% this stuff is worth it, you can buy me a beer in return. -% ---------------------------------------------------------------------------- - -\selectlanguage{german} -\begin{titlepage} % enlarge page - \pagestyle{empty} - \setlength{\topmargin}{0pt} - \setlength{\headheight}{0pt} - \setlength{\headsep}{0pt} - \setlength{\footskip}{0pt} - \begin{center} - \begin{figure}[ht] - \centering - \includegraphics{images/fhac_logo.png} - \label{fig:tulogo} - \end{figure} - - \vspace*{1cm} - - {\Huge\bf DIPLOMARBEIT \\[1cm]} - {\Large\bf {\maintitle} \\} - - {~\\Durchgeführt an der} - - {\large Fachhochschule Aachen\\} - {\large Fachbereich Elektrotechnik und Informationstechnik} - - {Eupener Str. 70\\} - {D-52066 Aachen\\~\\} - - {mit Erstpr\"{u}fer und Betreuer } - {\large Prof. Dr.-Ing. Martin Oßmann} - - {und Zweitpr\"{u}fer} - {\large Prof. Dr. rer. nat. Heinrich Fassbender} - - {durch\\} - {\large\bfseries Paul C. B\"{u}tow\\[0.3cm] } - {\large Matr.Nr.: 266617\\} - {Matthiashofstr. 15\\} - {D-52064 Aachen\\} - \end{center} - - \vspace*{0.5cm} - - \begin{flushleft} - {Aachen, \today \\} - \end{flushleft} - -\end{titlepage} - -\thispagestyle{empty} - ~ ~ -\newpage - -\vspace*{2cm} -\textbf{\LARGE Erkl\"{a}rung} -\vspace*{1.5cm} - -Ich versichere hiermit, dass ich die vorliegende Arbeit selbstst\"{a}ndig verfasst und keine anderen, als die im Literaturverzeichnis angegebenen Quellen benutzt habe. - -Stellen, die w\"{o}rtlich oder sinngem\"{a}ß aus ver\"{o}ffentlichten oder noch nicht ver\"{o}ffentlichten Quellen entnommen sind, sind als solche kenntlich gemacht. - -Die Zeichnungen oder Abbildungen in dieser Arbeit sind von mir selbst erstellt worden oder mit einem entsprechenden Quellennachweis versehen. - -Diese Arbeit ist in gleicher oder \"{a}hnlicher Form noch bei keiner anderen Pr\"{u}fungsbeh\"{o}rde eingereicht worden. - -Aachen, \today \\ - -\vspace*{2cm} -\textbf{\LARGE Geheimhaltung} -\vspace*{1.5cm} - -Diese Diplomarbeit darf weder vollst\"{a}ndig, noch auszugsweise ohne schriftliche Zustimmung des Autors, des betreuenden Referenten bzw. der Fachhochschule, Aachen vervielf\"{a}ltigt, ver\"{o}ffentlicht oder Dritten zug\"{a}nglich gemacht werden. - -\newpage - -\thispagestyle{empty} - ~ ~ -\newpage - -\vspace*{2cm} -\textbf{\LARGE Danksagungen} -\vspace*{1.5cm} - -Ohne die Hilfe folgender Personen w\"{a}re die Anfertigung dieser Diplomarbeit in diesem Maße nicht m\"{o}glich gewesen. Daher m\"{o}chte ich mich bedanken bei: - -\begin{itemize} - \item Prof. Oßmann als 1. Pr\"{u}fer sowie Prof. Fassbender als 2. Pr\"{u}fer - \item Andre Herbst - \item Carrie Callahan - \item Claudia Steudter - \item Florian B\"{u}tow - \item J\"{o}rn B\"{u}tow - \item Jochen Demmer - \item Leslie B\"{u}tow -\end{itemize} - -Auch vielen Dank an die Open Source Gemeinde, denn diese Diplomarbeit wurde ausschließlich mit Hilfe von Open Source Software angefertigt. - -\newpage -\thispagestyle{empty} - ~ ~ -\newpage - -\tableofcontents - -\listoffigures - -\listoftables - |
