Erstellen von Ereignistypen

Dieses Thema enthält Richtlinien für das Erstellen von Ereignistypen. Ein Ereignistyp definiert die Ereignisse, die von der Ereignisquelle veröffentlicht oder von der Ereignissenke genutzt werden. In der Entwicklung werden sie als einzelne primitive Typen oder als .NET Framework-Klassen oder -Strukturen angegeben und definieren die Daten (Nutzlast), die jedem Ereignis im Ereignisdatenstrom zugeordnet sind. Ereignistypen werden in den folgenden Phasen der Entwicklung verwendet:

  1. Schreiben eines typisierten Adapters. Ein typisierter Adapter verwendet den Ereignistyp als generischen Parameter, damit beim Erstellen von neuen Ereignisobjekten, die in die Warteschlange eingereiht werden sollen, die richtige Struktur initialisiert wird.

  2. Schreiben einer Abfragevorlage. Eine Abfragevorlage wird in LINQ über einem CepStream-Objekt angegeben, dessen Definition auf einem Ereignistyp basiert.

Weitere Informationen zu Ereignissen und Ereignisdatenströmen finden Sie unter StreamInsight-Serverkonzepte.

Festlegen der Ereignisstruktur

Wenn die Ereignisnutzlast (d. h. die Anzahl der Felder in der Nutzlast und ihre Typen) festgelegt und im Voraus bekannt ist, können Sie einen typisierten Adapter erstellen. Mit einem typisierten Adapter erzeugen alle Instanzen des Adapters das gleiche feste Nutzlastformat. Dies ist in der Regel der Fall für Ereignisquellen mit einer festen Datenstruktur.

Wenn Sie einen typisierten Adapter erstellen, definieren Sie eine .NET-Klasse oder -Struktur, die die feste Nutzlast darstellt. Oder verwenden Sie einen primitiven Typ, wenn die Ereignisnutzlast durch ein einzelnes Feld dargestellt werden kann. Bei Verwendung von Strukturen oder Klassen können Sie nur öffentliche Felder und Eigenschaften als Nutzlastfelder verwenden. Private Felder und Eigenschaften sowie Klassenmethoden werden ignoriert und können nicht im Ereignistyp verwendet werden. Sie verwenden diese Ereignistypdeklaration, um den Ereignistyp im Eingabeadapter aufzufüllen und das Ergebnis aus dem typisierten Ereignistyp im Ausgabeadapter abzurufen. Im folgenden Beispiel wird ein einfacher Ereignistyp definiert, der zwei Nutzlastfelder vom Typ int aufweist: V1 und V2.

    public class MyPayload
    {
        public int V1 { get; set; }
        public int V2 { get; set; }
    }

In diesem Beispiel wird die Verwendung eines geschachtelten Ereignistyps veranschaulicht:

    public class ComplexPayload
    {
        public ValueType Value { get; set; }
        public bool Status  { get; set; }
    }

    public class ValueType
    {
        public double Value { get; set; }
        public int Quality  { get; set; }
    }

Ein nicht typisierter Adapter ist nützlich, wenn der gleiche Adapter für eine bestimmte Quelle oder Senke konfigurierbar sein soll, sodass er mehrere Ereignistypen behandeln kann. Das Ereignisnutzlastformat für diese Ereignistypen wird für den Adapter als Teil einer Konfigurationsspezifikation bereitgestellt, wenn der Adapter an die Abfrage gebunden wird. Ein Beispiel für ein solches Szenario ist eine CSV-Datei, die eine veränderliche Anzahl von Feldern enthält. Der genaue Satz von Feldern, die eine Nutzlast bilden, kann vom Abfrage-Designer (und nicht vom Entwickler, der den Adapter erstellt) nur zur Zeit der Bindung und Instanziierung der Abfrage bestimmt werden. Ein anderes Beispiel ist ein Adapter für SQL-Tabellen, wenn der Typ der Ereignisse, die erzeugt werden, vom Schema der Tabelle oder von der Abfrage für die Tabelle abhängig ist. Weitere Informationen finden Sie unter Erstellen von Eingabe- und Ausgabeadaptern.

Die Spezifikation einer Abfragevorlage basiert auf einem CepStream-Objekt mit einem bestimmten Ereignistyp, der zur Entwurfszeit bekannt sein muss. CepStream-Zwischenobjekte in der Abfragevorlagenspezifikation können neue Typen enthalten, die implizit mit init-Memberausdrücken in Projektklauseln definiert werden ("select" in LINQ).

Anforderungen an Nutzlastfelder

Berücksichtigen Sie beim Erstellen von Ereignistypen die folgenden Nutzlastfeldanforderungen und die folgende Funktionalität.

  • Eine Ereignisstruktur kann nicht über eine leere Nutzlaststruktur verfügen. Mindestens ein Feld muss angegeben werden.

  • Sowohl skalare und elementare .NET Framework-Typen als auch geschachtelte Typen können für die Nutzlastfelder verwendet werden. Weitere Informationen finden Sie im folgenden Abschnitt "Unterstützte Datentypen".

  • Felder können nicht mittels benutzerdefinierter Attribute geändert werden.

  • Ereignistypen auf dem StreamInsight-Server stellen eine geordnete Liste von Feldern anstelle von .NET-Strukturen dar, die ihren Feldern keine Reihenfolge auferlegen. Die Reihenfolge von Ereignisfeldern ist für nicht typisierte Adapter wichtig. Diese Adapter greifen nach ordinal auf Felder zu, da die Felder zur Adapterentwurfszeit nicht bekannt sind. Im Rahmen der Standardkonvention ordnet eine .NET-Struktur, die als Ereignistyp verwendet wird, ihre Felder nach der lexikografischen Reihenfolge der Namen an. 

  • Die Nullfähigkeit des Felds wird abgeleitet. Beispielsweise ist int? nullfähig, int jedoch nicht. String und byte-[]-Typen sind immer nullfähig.

  • Die Standardgröße von byte[] ist 512.

  • Die maximale Länge von Zeichenfolgenfeldern ist nur an die Seitengröße (16 KB) für das gesamte Ereignis gebunden.

Ereignisgröße

Es gibt keine explizite Einschränkung für die Anzahl der Felder, die im Ereignistyp definiert werden können. Die Anzahl der Felder hängt vom Typ der einzelnen Felder, ihrer Größe und der Nullfähigkeit ab.

Die Ereignisseitengröße im StreamInsight-Server beträgt 16K. Da ein Ereignis nicht mehrere Seiten umfassen kann, sind 16K abzüglich eines Overheads die effektive maximale Ereignisgröße (einschließlich Nutzlast und Zeitstempelfelder). Zusätzlich zum festen, von Seitenkopf, Ereignisheader und Systemfeldern wie dem Zeitstempel verursachten Overhead erhöht die Nullfähigkeit den variablen Overhead um N/8 (an Obergrenze angepasst).

Zum Maximieren der Ereignisseitenauslastung werden die folgenden Richtlinien empfohlen:

  • Vermeiden Sie Felder, die NULL-Werte zulassen.

  • Minimieren Sie die Verwendung von string-Feldern und byte[]-Feldern.

  • Behalten Sie die Ereignislebensdauer nur solange bei wie von der Semantik des jeweiligen Szenarios gefordert, damit der für den Ereignisstatus benötigte Arbeitsspeicher im Modul effizienter freigegeben werden kann.

Erkennbarkeit von Ereignistypen

Sobald ein Ereignistyp erstellt wurde, besteht der nächste Schritt darin, seine Erkennbarkeit durch abhängige Projekte sicherzustellen. Beachten Sie, dass die .NET-Umgebung Entwicklern die Möglichkeit bietet, Module lose gekoppelt und verteilt zu erstellen und als Assemblys zu versenden. Diese Assemblys können dann zum Erstellen einer integrierten Anwendung zusammengefügt, getestet und für die Produktion bereitgestellt werden.

Beachten Sie außerdem, dass eine ausführbare StreamInsight-Abfrage das Ergebnis einer erfolgreichen Bindung einer Abfragevorlage an Instanzen von Eingabe- und Ausgabeadaptern ist, auf Grundlage von zusammenpassenden Ereignistypen bei der Eingabe und der Ausgabe der Abfrage. Abhängig von der Entwicklungsumgebung müssen Sie möglicherweise Zugriff auf den Ereignistyp für andere bereitstellen. Der Adapterentwickler und der Abfrageentwickler müssen z. B. möglicherweise an ihren jeweiligen Modulen unabhängig voneinander arbeiten. Betrachten Sie die folgenden Szenarien für die Erkennbarkeit von Ereignistypen:

  • Wenn der Adapterentwickler der Verleger des Ereignistyps ist, kann der Adapterentwickler den Adapter mittels der verwalteten StreamInsight-API schreiben und die .NET-Assembly versenden. Andere Entwickler können mittels "ildasm.exe" oder durch Verweisen auf die DLL aus dem Visual Studio-Projekt über die .NET-Assembly reflektieren und den Ereignistyp bestimmen. Wenn diese Methode verwendet wird, ist kein Zugriff auf den StreamInsight-Server erforderlich, um auf den Ereignistyp zuzugreifen.

  • Wenn der StreamInsight-Serveradministrator der Verleger des Ereignistyps ist, kann der Administrator oder der Entwickler den Ereignistyp im StreamInsight-Server bereitstellen. Ein Abfrageentwickler, der Zugriff auf den StreamInsight-Server hat, kann dann die anwendbaren Objektmodell-API-Aufrufe verwenden, um Metadatenelemente zu überprüfen und den Ereignistyp zu bestimmen. Der Adapterentwickler kann auch einen typisierten Adapter schreiben, der diesen Ereignistyp unterstützt.

  • Wenn der Adapterentwickler und der Abfrageentwickler nicht miteinander verbunden sind (jeder arbeitet mit einer eigenen Darstellung eines allgemeinen Ereignistyps), erfolgt die Überprüfung einer Übereinstimmung zwischen ihren jeweiligen Ereignistypen zur Abfragebindungszeit. Die Bindung ist erfolgreich, wenn es eine Übereinstimmung gibt.

  • Wenn der Abfrageentwickler keinen Zugriff auf die Adapterassembly oder den StreamInsight-Server hat, in dem der Adapter registriert ist, kann der Entwickler den Ereignistyp anhand der Produktdokumentation für den Adapter oder durch allgemeines Wissen über die für diese Domäne spezifischen Datenübertragungsprotokolle (z. B. Financial Information Exchange (FIX) oder Reuters Market Data System (RMDS) für den Finanzmarkt) bestimmen.

Unterstützte Datentypen

In StreamInsight verfügt jedes Ereignisfeld und jeder Ausdruck über einen bestimmten Datentyp. StreamInsight unterstützt die folgenden Datentypen. Ereignisnutzlasten können auch geschachtelte Typen enthalten, die sich aus diesen Datentypen zusammensetzen.

Kurzer Name

.NET-Klasse

Typ

Breite in Bit

Bereich

byte

Byte

Ganze Zahl ohne Vorzeichen

8

0 bis 255

sbyte

Sbyte

Ganze Zahl mit Vorzeichen

8

-128 bis 127

byte[]

Byte[]1

byte

 

 

int

int32

Ganze Zahl mit Vorzeichen

32

-2.147.483.648 bis 2.147.483.647

uint

uint32

Ganze Zahl ohne Vorzeichen

32

0 bis 4294967295

short

int16

Ganze Zahl mit Vorzeichen

16

-32.768 bis 32.767

ushort

uint16

Ganze Zahl ohne Vorzeichen

16

0 bis 65535

long

int64

Ganze Zahl mit Vorzeichen

64

-9223372036854775808 bis 9223372036854775807

ulong

uint64

Ganze Zahl ohne Vorzeichen

64

0 bis 18446744073709551615

float

Single

Gleitkommatyp mit einfacher Genauigkeit

32

-3,4 × 1038 bis +3,4 × 1038

double

Double

Gleitkommatyp mit doppelter Genauigkeit

64

±5,0 × 10−324 bis ±1,7 × 10308

decimal

Decimal

Genauer dezimaler oder ganzzahliger Typ, der Dezimalzahlen mit 29 signifikanten Stellen darstellen kann

128

±1,0 × 10e−28 bis ±7,9 × 10e28

bool

Boolean

Logischer boolescher Typ

8

true oder false

datetime

DateTime

Datums- und Uhrzeitangaben mit Werten, die zwischen 00:00:00 am 1. Januar 0001 nach Christus und 23:59:59 am 31. Dezember 9999 nach Christus liegen. (u. Z.)

 

 

timespan

TimeSpan

Die Anzahl der Takte, die dem dargestellten Zeitintervall entsprechen. Ein Takt entspricht 100 Nanosekunden.

 

Int64.MinValue-Takte bis Int64.MaxValue-Takte

guid

guid

Global eindeutiger Bezeichner

128

 

char

Char

Ein Unicode-Zeichen.

16

U+0000 bis U+ffff

string

String1

Eine Sequenz von Unicode-Zeichen

 

 .

1 Schließt keinen Typ ein, der NULL-Werte zulässt.

Bei der Adapterentwicklung werden Ereigniszeitstempel mit dem DataTimeOffset-Typ angegeben. Jedoch wird nur der DateTime-Typ in der Definition der Ereignistypnutzlastfelder unterstützt. In Szenarien, in denen Sie Daten des Typs DateTimeOffset in ein Ereignisfeld importieren, müssen Sie die Daten in DateTime als UTC konvertieren. Ein Nutzlastfeld kann z. B. aus einer SQL Server-Datenbank ausgefüllt werden oder indem Ereigniszeitstempelfelder zur Berechnung in Nutzlastfelder kopiert werden.

Siehe auch

Konzepte

Erstellen von Eingabe- und Ausgabeadaptern

StreamInsight-Serverkonzepte

StreamInsight-End-to-End-Beispiel