Creazione di tipi di evento

In questo argomento verranno fornite le linee guida per la creazione dei tipi di evento. Un tipo di evento consente di definire gli eventi pubblicati dall'origine evento o utilizzati dal sink di evento. Durante lo sviluppo, vengono specificati come singoli tipi primitivi, come classi .NET Framework o struct e consentono di definire i dati (payload) associati a ogni evento nel flusso di eventi. I tipi di evento vengono utilizzati nelle fasi seguenti dello sviluppo:

  1. Scrittura di un adattatore tipizzato. Un adattatore tipizzato utilizza il tipo di evento come parametro generico in modo che venga inizializzata la struttura appropriata quando vengono creati nuovi oggetti evento da accodare.

  2. Scrittura di un modello di query. Un modello di query viene specificato in LINQ in un oggetto CepStream la cui definizione è basata su un tipo di evento.

Per ulteriori informazioni sugli eventi e sui flussi di eventi, vedere Concetti relativi al server StreamInsight.

Determinare la struttura dell'evento

Quando il payload dell'evento, ovvero il numero di campi nel payload e i relativi tipi, è fisso e noto in anticipo, è possibile creare un adattatore tipizzato. Con un adattatore tipizzato, tutte le istanze dell'adattatore producono lo stesso formato di payload fisso. Questo avviene, in genere, con le origini evento con una struttura di dati fissa.

Quando si crea un adattatore tipizzato, si definisce uno struct o classe .NET che rappresenta il payload fisso oppure è possibile utilizzare un tipo primitivo se il payload dell'evento può essere rappresentato da un solo campo. Quando si utilizzano struct o classi, è possibile utilizzare solo proprietà e campi pubblici come campi payload. Le proprietà e i campi privati, nonché i metodi della classe, vengono ignorati e non possono essere utilizzati nel tipo di evento. Questa dichiarazione di tipo di evento viene utilizzata per popolare il tipo di evento nell'adattatore di input e ottenere il risultato dall'evento tipizzato nell'adattatore di output. Nell'esempio seguente viene definito un tipo di evento semplice che dispone di due campi payload, V1 e V2, di tipo int.

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

In un altro esempio viene mostrato come utilizzare un tipo di evento nidificato:

    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; }
    }

Un adattatore non tipizzato è utile quando si desidera che lo stesso adattatore per un'origine o un sink specifico sia configurabile in modo da poter gestire più tipi di evento. Il formato di payload dell'evento per questi tipi di evento viene fornito all'adattatore come parte di una specifica di configurazione quando l'adattatore viene associato alla query. Un esempio di uno scenario di questo tipo è costituito da un file csv contenente un numero variabile di campi. Il set esatto di campi che costituiscono un payload può essere determinato da Progettazione query, e non dallo sviluppatore che compila l'adattatore, solo al momento dell'associazione e della creazione di un'istanza della query. Un altro esempio è costituito da un adattatore per le tabelle SQL, dove il tipo degli eventi prodotti dipende dallo schema della tabella o della query eseguita nella tabella. Per ulteriori informazioni, vedere Creazione di adattatori di input e di output.

La specifica di un modello di query è basata su un oggetto CepStream con un tipo di evento specifico, che deve essere noto in fase di progettazione. Gli oggetti CepStream intermedi lungo la specifica del modello di query possono contenere nuovi tipi definiti in modo implicito nelle clausole del progetto ("select" in LINQ), utilizzando espressioni init dei membri.

Requisiti dei campi payload

Quando si creano tipi di evento, prendere in considerazione le funzionalità e i requisiti dei campi payload seguenti.

  • In una struttura di eventi non può essere inclusa una struttura di payload vuota. È necessario che sia presente almeno un campo.

  • Per i campi payload possono essere utilizzati sia i tipi nidificati sia i tipi .NET Framework scalari ed elementari. Vedere la sezione "Tipi di dati supportati" più avanti.

  • I campi non possono essere modificati utilizzando attributi personalizzati.

  • I tipi di evento nel server StreamInsight sono un elenco ordinato di campi anziché struct .NET che non impongono un ordine nei campi. L'ordine di campi evento diventa importante per gli adattatori non tipizzati. Questi adattatori consentono l'accesso ai campi in base a ordinal, dal momento che i campi non sono noti nella fase di progettazione dell'adattatore. Per convenzione predefinita, uno struct .NET, utilizzato come tipo di evento, ordina i campi in base all'ordine lessicografico dei nomi. 

  • La possibilità di utilizzare valori Null nel campo viene derivata. int?, ad esempio, ammette valori Null, mentre int no. I tipi String e byte[] ammettono sempre valori Null.

  • Le dimensioni predefinite di byte[] sono 512.

  • La lunghezza massima dei campi stringa viene associata solo in base alle dimensioni della pagina per l'evento intero che sono 16k byte.

Dimensioni degli eventi

Non vi sono limitazioni esplicite al numero di campi che è possibile definire nel tipo di evento. Il numero di campi dipende dal tipo dei singoli campi, dalla loro dimensione e dalla possibilità di utilizzare valori Null.

Le dimensioni della pagina di un evento nel server StreamInsight sono di 16K. Poiché un evento non può estendersi in più pagine, 16K meno l'overhead è il valore effettivo delle dimensioni massime di un evento (inclusi campi timestamp e payload). Oltre all'overhead fisso legato a intestazione della pagina, intestazione dell'evento e campi di sistema come il timestamp, la possibilità di utilizzare valori Null comporta un'aggiunta al valore dell'overhead variabile nell'ordine di N/8, arrotondato al valore superiore.

Per ottimizzare l'utilizzo della pagina dell'evento, è consigliabile rispettare le linee guida seguenti:

  • Evitare campi che ammettono valori NULL.

  • Ridurre al minimo l'utilizzo di campi string e byte[].

  • La durata dell'evento deve corrispondere a quanto richiesto dalla semantica del rispettivo scenario, in modo che la memoria necessaria per lo stato dell'evento possa essere rilasciata più efficientemente nel motore

Individuazione dei tipi di evento

Una volta creato un tipo di evento, il passaggio successivo consiste nel consentirne l'individuazione da parte dei progetti dipendenti. Si noti che l'ambiente .NET consente agli sviluppatori di compilare moduli a regime di controllo libero ("loosely-coupled") e in modo distribuito e di fornirli come assembly. Questi assembly possono essere raggruppati per compilare un'applicazione integrata, testati e distribuiti nell'ambiente di produzione.

Tenere presente che una query di StreamInsight eseguibile è il risultato della corretta associazione di un modello di query con istanze di adattatori di input e output, in base a tipi di eventi corrispondenti nelle posizioni di input e output della query. A seconda dell'ambiente di sviluppo, potrebbe essere necessario fornire ad altri utenti l'accesso al tipo di evento. È ad esempio possibile che lo sviluppatore dell'adattatore e lo sviluppatore della query debbano lavorare indipendentemente sui rispettivi moduli. Si considerino gli scenari seguenti per l'individuazione del tipo di evento:

  • Se lo sviluppatore dell'adattatore è l'autore del tipo di evento, lo sviluppatore dell'adattatore può scrivere l'adattatore utilizzando l'API gestita di StreamInsight e fornire l'assembly .NET. Gli altri sviluppatori possono basarsi sull'assembly .NET utilizzando ildasm.exe o facendo riferimento alla DLL dal progetto Visual Studio e determinare il tipo di evento. Se si utilizza questo metodo, l'accesso al server StreamInsight non è necessario per accedere al tipo di evento.

  • Se l'amministratore del server StreamInsight è l'autore del tipo di evento, l'amministratore o lo sviluppatore può distribuire il tipo di evento nel server StreamInsight. Uno sviluppatore di query che dispone di accesso al server StreamInsight può utilizzare le chiamate all'API del modello a oggetti applicabile per analizzare gli elementi di metadati e determinare il tipo di evento. Lo sviluppatore dell'adattatore può inoltre scrivere un adattatore tipizzato che supporta questo tipo di evento.

  • Se lo sviluppatore dell'adattatore e lo sviluppatore della query sono disconnessi, ognuno lavora con la propria rappresentazione di un tipo di evento comune, la convalida di una corrispondenza tra i rispettivi tipi di evento avviene al momento dell'associazione della query. Se la corrispondenza riesce l'associazione viene completata.

  • Se lo sviluppatore di query non dispone di accesso all'assembly dell'adattatore o al server StreamInsight in cui è registrato l'adattatore, lo sviluppatore può determinare il tipo di evento facendo riferimento alla documentazione del prodotto per l'adattatore o tramite conoscenze comuni relative ai protocolli di trasferimento dati specifici per tale dominio, ad esempio FIX (Financial Information Exchange) o RMDS (Reuters Market Data System) per le compravendite finanziarie.

Tipi di dati supportati

In StreamInsight ogni campo evento e ogni espressione dispone di un tipo di dati specifico. StreamInsight supporta i tipi di dati seguenti. Nei payload dell'evento possono inoltre essere contenuti tipi nidificati che sono composti di questi tipi di dati.

Nome breve

Classe .NET

Tipo

Larghezza in bit

Intervallo

byte

Byte

Intero senza segno

8

Da 0 a 255

sbyte

Sbyte

Intero con segno

8

Da -128 a 127

byte[]

Byte[]1

byte

 

 

int

int32

Intero con segno

32

Da -2.147.483.648 a 2.147.483.647

uint

uint32

Intero senza segno

32

Da 0 a 4294967295

short

int16

Intero con segno

16

Da -32.768 a 32.767

ushort

uint16

Intero senza segno

16

Da 0 a 65535

long

int64

Intero con segno

64

Da -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807

ulong

uint64

Intero senza segno

64

Da 0 a 18446744073709551615

float

Single

Tipo a virgola mobile a precisione singola

32

Da -3,4 × 1038 a +3,4 × 1038

double

Double

Tipo a virgola mobile a precisione doppia

64

Da ±5,0 × 10−324 a ±1,7 × 10308

decimal

Decimal

Tipo integrale o frazionario preciso che può rappresentare numeri decimali con 29 cifre significative

128

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

bool

Boolean

Tipo booleano logico

8

true o false

datetime

DateTime

Date e ore con valori che variano da 12:00:00 (mezzanotte), 1 gennaio, 0001 DC (era cristiana) a 11:59:59 PM, 31 dicembre 9999 DC. (E.V.)

 

 

timespan

TimeSpan

Numero di tick equivalente all'intervallo di tempo rappresentato. Un tick corrisponde a 100 nanosecondi

 

Da Int64.MinValue tick a Int64.MaxValue tick

guid

guid

Identificatore univoco globale

128

 

char

Char

Carattere Unicode

16

Da U+0000 a U+ffff

string

String1

Sequenza di caratteri Unicode

 

 .

1 Non include tipi che ammettono valori NULL.

Durante lo sviluppo dell'adattatore, i timestamp dell'evento vengono specificati utilizzando il tipo DataTimeOffset. Tuttavia, solo il tipo DateTime è supportato nella definizione dei campi payload del tipo di evento. In scenari in cui si importano dati di tipo DateTimeOffset in un campo evento, è necessario convertire i dati in formato DateTime di tipo UTC. È ad esempio possibile che in un campo vengano inseriti valori da un database di SQL Server o copiando i campi timestamp degli eventi in campi payload per il calcolo.

Vedere anche

Concetti

Creazione di adattatori di input e di output

Concetti relativi al server StreamInsight

Esempio end-to-end di StreamInsight