Ü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.

_images/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.