Überblick über die Library ########################## Die Hauptklasse der Library ist der **Kernel**, bzw. das Interface ``IKernel``. Die Library kann durch einfaches Instanziieren der Klasse ``CKernel`` benutzt werden. .. image:: KernelOutline.PNG Targets ******* Die Klasse, mit der Programmierer am häufigsten arbeiten, ist die **Target**-Klasse. Targets senden und empfangen **Messages**. Um das zu ermöglichen, werden sie in der **TargetRegistry** registriert. Ein Target erhält dabei eine ID, die Target-ID (kurz: **TID**). Man kann den Targets eigene TIDs geben; gewöhnlich reicht jedoch eine von der TargetRegistry generierte zufällige ID. Targets werden bei der Registrierung an einen Thread gebunden. Alle Messages, welche sie im Laufe ihres Lebens erhalten, werden sie immer in demselben Thread erhalten. Es werden niemals Messages zur selben Zeit an das Target gereicht, sondern sie kommen immer nacheinander in die Verarbeitung. Daher braucht man sich hier keine Gedanken um Probleme der Nebenläufigkeit zu machen. Services ******** Targets betreiben Micro-Services. Dazu registrieren sie so genannte **Services** in einer **ServiceRegistry**. Die Services haben eine eigene Service-ID (kurz: **SID**). Im Gegensatz zu den TID sind die SID dokumentiert und wohl bekannt, also konstant. So können auch Services benutzt werden, die in fremden devel.one-Instanzen angeboten werden. SoftDevel betreibt eine Registratur an bekannten Services; die Verwendung dieser dokumentierten Services wird ausdrücklich empfohlen. Jeder kann Services zur Dokumentation einreichen. Daher schickt man meist weniger Messages an ein (eher anonymes) Target, sondern an einen Service. An Services kann man auch **Observer** registrieren, die jede Nachricht in Kopie bekommen, welche an einen Service gerichtet ist. Aus diesem Grund werden Services auch für das Informations-Management verwendet. Notifikationen werden einfach an einen dafür eingerichteten Service geschickt, und alle Interessenten bekommen die Mitteilung in Kopie. Namespaces ********** Da mehrere Instanzen derselben Applikation in einer devel.one-Instanz laufen können, genügt eine TID nicht zur vollständigen Identifikation eines Targets. Daher gibt es so genannte **Namespaces**, welche eine Applikation kapseln. Jeder Namespace hat eine eigene Namespace-ID (kurz: **NID**). Namespaces betreiben eigene TargetRegistries, an denen Targets angemeldet werden können. Da Namespaces auch mehrere **Threads** betreiben können, muss bei der Registrierung eines Targets auch die MessageQueue-ID (kurz: *QID*) angegeben werden. Entfällt die Angabe hier, so wird das Target für den ersten Thread angemeldet. Außerdem besitzen Namespaces eine eigene ServiceRegistry. Services sind also immer spezifisch für einen Namespace. Der devel.one Kernel betreibt immer einen Namespace **SYSTEM**. Wenn also Services betrieben werden sollen, welche für die gesamte devel.one-Instanz stehen, so bietet sich die Registrierung der Services in diesem Namespace an. PlugIns registrieren noch weitere System-Namespaces, wenn sie denn geladen werden. Dazu gehört insbesondere der Namespace **TRANSPORT** für alle Kommunikationsservices, **TEST** für Test-Frameworks und **MONITOR** für die Tool-UserInterfaces. Kernel ****** Namespaces werden in einer **NamespaceRegistry** registriert, welche im **Kernel** sitzt. Außerdem besitzt der Kernel etliche weitere SubSysteme: - Der **TimerManager** schickt Messages nach Ablauf einer Zeitspanne zu. Timer können auch wiederholt ausgelöst werden, vor dem Ablauf wieder gelöscht werden, und sie können auch Daten mitführen. - Die ListenerRegistry dient zum Betreiben von Observer/Observable Benachrichtigungen. Da in einem dynamischen System Targets und Verbindungen wegfallen können, sorgt dieser Service für ein Tracken aller beteiligten Targets. Das verhindert, das Benachrichtigungen an Observer geschickt werden, welle es schon lange gar nicht mehr gibt. - Die MessageDatabase ist ein Katalog aller bekannten Nachrichten und dient zum Beispiel dem Logging-SubSystem, um Messages und Parameter beim Namen zu nennen. - Die NameDb ist eine weitere Namens-Datenbank und hat eine ähnliche Funktion wie die Message-Database. Insbesondere IDs werden hier mit Namen verbunden. - Die SignalRegistry verwaltet synchrone low-level Signale und deren Observer. Sie dient auch in 1-Thread-Umgebungen wie dem Swing-Thread als Messaging Basis. - Der Datapool ist eine Art Registry für Variablen, auf die synchron oder asynchron mit Keys zugegriffen wird. Auch hier lassen sich Observer verwenden, um bei Änderungen von Variablen informiert zu werden. Sie hat auch eine zentrale Bedeutung für die Konfiguration. Messages ******** Messages sind in devel.one das zentrale Kommunikationsmittel. Eine Nachricht transportiert diverse Daten, welche in so genannten **Records** gehalten werden. Records wiederum bestehen aus einer ID sowie den **Slots** (den eigentlichen Daten). Gewöhnlich trägt eine Message nur einen Record mit sich. Die Slots der Records werden in einer HashMap gehalten, der Zugriff erfolgt über einen **SlotKey**. Der SlotKey besteht aus zwei **IDs**. Damit sind zum Beispiel ähnliche Zugriffe wie auf die Variablen der Windows-Registry möglich, mit Path+VarKey. Immer wiederkehrende SlotKeys bestehen oft auch als kollisionssichere GUIDs, insbesondere bei Fernzugriffen im Internet. Es gibt zur Zeit etwa drei Dutzend SlotTypes: - LowLevel Typen wie Boolean, Byte, Char, Short, Integer, Long, String, Float, Double sowie deren Arrays - zusammengesetzte Typen wie IDs, TargetAddress, GUID etc. sowie deren Arrays. Messages sind im gepackten Zustand sehr klein (binär). Außerdem sind sie plattformunabhängig, da ihre Zusammensetzung dokumentiert ist. Zudem werden Nachrichten komprimiert und verschlüsselt verschickt.