Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
I grani in Orleans ciascuno ha un identificatore univoco, definito dall'utente, costituito da due parti:
- Nome del tipo di grano, che identifica in modo univoco la classe del grano.
- La chiave grano, identifica in modo univoco un'istanza logica di quella classe di grano.
Orleans rappresenta sia il tipo di granularità che la chiave come stringhe leggibili dall'utente. Per convenzione, scrivere l'identità del granello con il tipo di granello e la chiave separati da un carattere /. Ad esempio, shoppingcart/bob65 rappresenta il tipo di granularità denominato shoppingcart con la chiave bob65.
La creazione diretta di identità granulari non è comune. La creazione di riferimenti granulari tramite Orleans.IGrainFactory è invece più comune.
Le sezioni seguenti illustrano in modo più dettagliato i nomi dei tipi di granularità e le chiavi granulari.
Nomi dei tipi di granularità
Orleans crea un nome di tipo granulare basato sulla classe di implementazione granulare. Rimuove il suffisso "Grain" dal nome della classe, se presente, e converte la stringa risultante nella relativa rappresentazione minuscola. Ad esempio, una classe denominata ShoppingCartGrain riceve il nome shoppingcartdel tipo di granularità . È consigliabile che i nomi e le chiavi dei tipi di granularità siano costituiti solo da caratteri stampabili, ad esempio caratteri alfanumerici (a-z,A-Z e0-9 ) e simboli come -, _@, e .= Altri caratteri potrebbero non essere supportati e spesso richiedono un trattamento speciale quando vengono stampati nei log o visualizzati come identificatori in altri sistemi, ad esempio i database.
In alternativa, usare l'attributo Orleans.GrainTypeAttribute per personalizzare il nome del tipo di granularità per la classe granulare a cui è associato, come illustrato nell'esempio seguente:
[GrainType("cart")]
public class ShoppingCartGrain : IShoppingCartGrain
{
// Add your grain implementation here
}
Nell'esempio precedente la classe ShoppingCartGrain granulare ha il nome cartdel tipo di granularità . Ogni granularità può avere un solo nome di tipo granulare.
Per granelli generici, includere l'arità generica nel nome del tipo di granello. Si consideri ad esempio la classe seguente DictionaryGrain<K, V> :
[GrainType("dict`2")]
public class DictionaryGrain<K, V> : IDictionaryGrain<K, V>
{
// Add your grain implementation here
}
La classe grain ha due parametri generici, quindi un backtick ` seguito dall'arità generica, 2, viene aggiunto alla fine del nome del tipo grain dict per creare il nome del tipo grain dict`2. Questo valore viene specificato nell'attributo nella classe granulare: [GrainType("dict2")]'.
Chiavi di granularità
Per praticità, Orleans espone i metodi che consentono la costruzione di chiavi di granularità da un Guid oggetto o Int64, oltre a un oggetto String. La chiave primaria ha come ambito il tipo di granularità. Pertanto, l'identità completa di un chicco si forma dal suo tipo e dalla sua chiave.
Il chiamante del grano decide quale schema utilizzare. Le opzioni sono:
Poiché i dati sottostanti sono gli stessi, gli schemi possono essere usati in modo intercambiabile: sono tutti codificati come stringhe.
Le situazioni che richiedono un'istanza di granularità singleton possono usare un valore fisso noto, ad esempio "default". Si tratta semplicemente di una convenzione, ma aderirvi chiarisce nel contesto chiamante che si sta utilizzando un singleton grain.
Uso di identificatori univoci globali (GUID) come chiavi
System.Guid rendere chiavi utili quando si desiderano la casualità e l'univocità globale, ad esempio quando si crea una nuova attività in un sistema di elaborazione attività. Non è necessario coordinare l'allocazione delle chiavi, che potrebbe introdurre un singolo punto di guasto o un blocco del sistema su una risorsa, creando potenzialmente un collo di bottiglia. La probabilità di collisioni GUID è molto bassa, rendendole una scelta comune quando si progettano sistemi che necessitano di allocazione di identificatori casuali.
Riferimento a un grain tramite GUID nel codice client:
var grain = grainFactory.GetGrain<IExample>(Guid.NewGuid());
Recupero della chiave primaria dal codice granulare:
public override Task OnActivateAsync()
{
Guid primaryKey = this.GetPrimaryKey();
return base.OnActivateAsync();
}
Uso di numeri interi come chiavi
È disponibile anche un numero intero lungo. Ciò ha senso se la granularità persiste in un database relazionale, in cui gli indici numerici sono spesso preferiti rispetto ai GUID.
Riferimento a un grano tramite un numero intero lungo nel codice client:
var grain = grainFactory.GetGrain<IExample>(1);
Recupero della chiave primaria dal codice granulare:
public override Task OnActivateAsync()
{
long primaryKey = this.GetPrimaryKeyLong();
return base.OnActivateAsync();
}
Uso di stringhe come chiavi
È disponibile anche una chiave stringa.
Riferimento a un oggetto tramite String nel codice client.
var grain = grainFactory.GetGrain<IExample>("myGrainKey");
Recupero della chiave primaria dal codice granulare:
public override Task OnActivateAsync()
{
string primaryKey = this.GetPrimaryKeyString();
return base.OnActivateAsync();
}
Uso di chiavi composte
Se il sistema non è adatto a GUID o longs, optare per una chiave primaria composta. In questo modo è possibile usare una combinazione di un GUID o long e una stringa per fare riferimento a un grano.
Ereditare l'interfaccia da IGrainWithGuidCompoundKey o IGrainWithIntegerCompoundKey come segue:
public interface IExampleGrain : Orleans.IGrainWithIntegerCompoundKey
{
Task Hello();
}
Nel codice client, questo aggiunge un secondo argomento al metodo della factory di grain:
var grain = grainFactory.GetGrain<IExample>(0, "a string!", null);
Per accedere alla chiave composta nel grano, chiamare un overload del metodo GetPrimaryKey (ad esempio GetPrimaryKeyLong):
public class ExampleGrain : Orleans.Grain, IExampleGrain
{
public Task Hello()
{
long primaryKey = this.GetPrimaryKeyLong(out string keyExtension);
Console.WriteLine($"Hello from {keyExtension}");
return Task.CompletedTask;
}
}
Perché i grani usano identificatori logici
Negli ambienti orientati agli oggetti come .NET, l'identità di un oggetto è difficile da distinguere da un riferimento. Quando un oggetto viene creato usando la new parola chiave , il riferimento restituito rappresenta tutti gli aspetti dell'identità, ad eccezione di quelli che esestituiscono l'oggetto a un'entità esterna rappresentata.
Orleans è progettato per i sistemi distribuiti. Nei sistemi distribuiti i riferimenti a oggetti non possono rappresentare l'identità dell'istanza perché sono limitati allo spazio indirizzi di un singolo processo.
Orleans usa identificatori logici per evitare questa limitazione. I grani usano identificatori logici in modo che i riferimenti granulari rimangano validi per tutta la durata del processo e siano portabili da un processo a un altro. In questo modo è possibile archiviarli e recuperarli in un secondo momento o inviarli in rete a un altro processo nell'applicazione, pur facendo ancora riferimento alla stessa entità: la granularità per cui è stato creato il riferimento.