Dela via


Kornig identitet

Korn i Orleans var och en har en enda, unik, användardefinierad identifierare som består av två delar:

  1. Korntypsnamnet, som unikt identifierar kornklassen.
  2. Kornnyckeln, som unikt identifierar en logisk instans av den korniga klassen.

Korntypen och nyckeln representeras båda som läsbara strängar i Orleans och enligt konventionen skrivs kornidentiteten med korntypen och nyckeln avgränsad med ett / tecken. Representerar till exempel shoppingcart/bob65 korntypen med namnet shoppingcart med en nyckel bob65.

Det är inte vanligt att konstruera kornidentiteter direkt. I stället är det vanligare att skapa kornreferenser med hjälp av Orleans.IGrainFactory.

I följande avsnitt beskrivs korntypsnamn och kornnycklar mer detaljerat.

Namn på korntyp

Orleans skapar ett korntypsnamn för dig baserat på din kornimplementeringsklass genom att ta bort suffixet "Grain" från klassnamnet, om det finns det, och konvertera den resulterande strängen till dess gemener. En klass med namnet ShoppingCartGrain får till exempel korntypsnamnet shoppingcart. Vi rekommenderar att namn och nycklar för korntyp endast består av utskrivbara tecken, till exempel alfanumeriska (a-z,-AZ och-09 ) tecken och symboler som -, _, @, . = Andra tecken kanske eller kanske inte stöds och behöver ofta särskild behandling när de skrivs ut i loggar eller visas som identifierare i andra system, till exempel databaser.

Alternativt kan attributet Orleans.GrainTypeAttribute användas för att anpassa korntypsnamnet för den kornklass som det är kopplat till, som i följande exempel:

[GrainType("cart")]
public class ShoppingCartGrain : IShoppingCartGrain
{
    // Add your grain implementation here
}

I föregående exempel har kornklassen ShoppingCartGrain ett korntypnamn på cart. Varje korn kan bara ha ett korntypnamn.

För generiska korn måste den generiska ariteten inkluderas i korntypsnamnet. Tänk till exempel på följande DictionaryGrain<K, V> klass:

[GrainType("dict`2")]
public class DictionaryGrain<K, V> : IDictionaryGrain<K, V>
{
    // Add your grain implementation here
}

Kornklassen har två generiska parametrar, så en backtick ` följt av den generiska arity, 2, läggs till i slutet av korntypsnamnet för dict att skapa korntypsnamnet dict`2, enligt vad som anges i attributet för kornklassen , [GrainType("dict`2")].

Korniga nycklar

För enkelhetens skull Orleans exponerar metoder som tillåter konstruktion av kornnycklar från en Guid eller en Int64, utöver en String. Primärnyckeln är begränsad till korntypen. Därför bildas den fullständiga identiteten för ett korn från korntypen och dess nyckel.

Anroparen av kornet bestämmer vilket schema som ska användas. Alternativen är:

Eftersom underliggande data är desamma kan scheman användas omväxlande: alla kodas som strängar.

Situationer som kräver en singleton grain-instans kan använda ett välkänt, fast värde, till exempel "default". Detta är bara en konvention, men genom att följa denna konvention blir det tydligt på uppringarens webbplats att ett singleton-korn används.

Använda globalt unika identifierare (GUID) som nycklar

System.Guid gör användbara nycklar när slumpmässighet och global unikhet önskas, till exempel när du skapar ett nytt jobb i ett jobbbearbetningssystem. Du behöver inte samordna allokeringen av nycklar, vilket kan medföra en felpunkt i systemet eller ett lås på systemsidan på en resurs som kan medföra en flaskhals. Det finns en mycket låg risk för att GUID:er kolliderar, så de är ett vanligt val när du utformar ett system som behöver allokera slumpmässiga identifierare.

Refererar till ett korn efter GUID i klientkoden:

var grain = grainFactory.GetGrain<IExample>(Guid.NewGuid());

Hämtar primärnyckeln från kornkod:

public override Task OnActivateAsync()
{
    Guid primaryKey = this.GetPrimaryKey();
    return base.OnActivateAsync();
}

Använda heltal som nycklar

Ett långt heltal är också tillgängligt, vilket skulle vara meningsfullt om kornet bevaras till en relationsdatabas, där numeriska index föredras framför GUID.

Refererar till ett korn med ett långt heltal i klientkoden:

var grain = grainFactory.GetGrain<IExample>(1);

Hämtar primärnyckeln från kornkod:

public override Task OnActivateAsync()
{
    long primaryKey = this.GetPrimaryKeyLong();
    return base.OnActivateAsync();
}

Använda strängar som nycklar

En sträng är också tillgänglig.

Refererar till ett korn efter sträng i klientkoden:

var grain = grainFactory.GetGrain<IExample>("myGrainKey");

Hämtar primärnyckeln från kornkod:

public override Task OnActivateAsync()
{
    string primaryKey = this.GetPrimaryKeyString();
    return base.OnActivateAsync();
}

Använda sammansatta nycklar

Om du har ett system som inte passar bra med antingen GUID eller longs kan du välja en sammansatt primärnyckel, som gör att du kan använda en kombination av ett GUID eller en lång och en sträng för att referera till ett korn.

Du kan ärva ditt gränssnitt från IGrainWithGuidCompoundKey eller IGrainWithIntegerCompoundKey så här:

public interface IExampleGrain : Orleans.IGrainWithIntegerCompoundKey
{
    Task Hello();
}

I klientkoden lägger detta till ett andra argument till IGrainFactory.GetGrain metoden på kornfabriken:

var grain = grainFactory.GetGrain<IExample>(0, "a string!", null);

För att få åtkomst till den sammansatta nyckeln i kornet kan vi anropa en överlagring av GrainExtensions.GetPrimaryKey metoden ( GrainExtensions.GetPrimaryKeyLongmetoden ):

public class ExampleGrain : Orleans.Grain, IExampleGrain
{
    public Task Hello()
    {
        long primaryKey = this.GetPrimaryKeyLong(out string keyExtension);
        Console.WriteLine($"Hello from {keyExtension}");

        Task.CompletedTask;
    }
}

Varför korn använder logiska identifierare

I objektorienterade miljöer, till exempel .NET, är det svårt att skilja ett objekts identitet från en referens till det. När ett objekt skapas med nyckelordet new representerar referensen som du får tillbaka alla aspekter av dess identitet förutom de som mappar objektet till en extern entitet som det representerar. Orleans är utformad för distribuerade system. I distribuerade system kan objektreferenser inte representera instansidentitet eftersom objektreferenser är begränsade till en enda process adressutrymme. Orleans använder logiska identifierare för att undvika den här begränsningen. Korn använder logiska identifierare så att kornreferenser förblir giltiga under hela processens livslängd och är portabla från en process till en annan, så att de kan lagras och senare hämtas eller skickas över ett nätverk till en annan process i programmet, samtidigt som de refererar till samma entitet: det korn som referensen skapades för.