粒紋身分識別

Orleans 中的每個粒紋都有一個單一且唯一的使用者定義識別碼,由兩個部分組成:

  1. 粒紋型別名稱,可唯一識別粒紋類別。
  2. 粒紋索引鍵,可唯一識別該粒紋類別的邏輯執行個體。

粒紋型別和索引鍵都以 Orleans 中人類可讀取的字串表示,並且根據慣例,粒紋識別是以 / 字元分隔的粒紋型別和索引鍵來撰寫。 例如,shoppingcart/bob65 表示名為 shoppingcart 且索引鍵為 bob65 的粒紋型別。

直接建構粒紋身分識別並不常見。 相反地,使用 Orleans.IGrainFactory 建立粒紋參考比較常見。

下列各節將更詳細地討論粒紋型別名稱和粒紋索引鍵。

粒紋型別名稱

Orleans 會根據您的粒紋實作類別為您建立粒紋型別名稱,方法是從類別名稱中移除尾碼「Grain」,並將結果字串轉換為其小寫表示法。 例如,名為 ShoppingCartGrain 的類別會指定粒紋型別名稱 shoppingcart。 建議粒紋型別名稱和索引鍵只包含可列印的字元,例如英數 (a-zA-Z0-9) 字元和符號,例如 -_@=。 其他字元可能受到支援,也可能不受支援,並且在記錄中列印或在其他系統中 (例如資料庫) 顯示為識別碼時,通常需要特殊處理。

或者,Orleans.GrainTypeAttribute 屬性可以用來自訂其附加之粒紋類別的粒紋型別名稱,如下列範例所示:

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

在上述範例中,粒紋類別 ShoppingCartGrain 的粒紋型別名稱為 cart。 每個粒紋只能有一個粒紋型別名稱。

針對泛型粒紋,泛型元數必須包含在粒紋型別名稱中。 例如,請參考下列 DictionaryGrain<K, V> 類別:

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

粒紋類別有兩個泛型參數,因此倒引號 ` 後面接著泛型元數 2,該元數新增至粒紋型別名稱的結尾,dict 以建立粒紋型別名稱 dict`2,如粒紋類別 [GrainType("dict`2")] 上的屬性所指定。

粒紋索引鍵

為了方便起見,除了 String 以外,Orleans 還公開了方法,以允許從 GuidInt64 建構粒紋索引鍵。 主索引鍵的範圍限定為粒紋型別。 因此,粒紋的完整身分識別會由粒紋的型別及其索引鍵組成。

粒紋的呼叫端將決定應使用哪個配置。 選項是:

由於基礎資料相同,配置可以互換使用:它們全部都編碼為字串。

需要單一資料庫粒紋執行個體的情況,可以使用已知的固定值,例如 "default"。 這只是慣例,但循此慣例,我們可在呼叫端網站清楚看出單一粒紋正在使用中。

使用全域唯一識別碼 (GUID) 作為索引鍵

當需要隨機性與全域唯一性時,例如在作業處理系統中建立新作業時,System.Guid 會建立有用的索引鍵。 您不需要協調可能在系統中導入單一失敗點的索引鍵配置,也無須協調資源上可能造成瓶頸的系統端鎖定。 GUID 衝突的可能性非常低,因此在建構需要配置隨機識別碼的系統時,它們是常見的選擇。

在用戶端程式碼中依 GUID 參考粒紋:

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

從粒紋程式碼擷取主索引鍵:

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

使用整數作為索引鍵

長整數也可供使用,如果粒紋會保存到關聯式資料庫 (在此處數值索引的優先權會高於 GUID),就很適用。

在用戶端程式碼中依長整數參考粒紋:

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

從粒紋程式碼擷取主索引鍵:

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

使用字串作為索引鍵

字串也可供使用。

在用戶端程式碼中依字串參考粒紋:

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

從粒紋程式碼擷取主索引鍵:

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

使用複合索引鍵

如果您的系統不適用 GUID 或 long,可以選擇複合主索引鍵,這可讓您使用 GUID 或 long 和字串的組合來參考粒紋。

您可以從 IGrainWithGuidCompoundKeyIGrainWithIntegerCompoundKey 介面繼承您的介面,如下所示:

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

在用戶端程式碼中,這會將第二個引數新增至粒紋處理站上的 IGrainFactory.GetGrain 方法:

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

若要存取粒紋中的複合索引鍵,我們可以在 GrainExtensions.GetPrimaryKey 方法 (GrainExtensions.GetPrimaryKeyLong) 上呼叫多載:

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

        Task.CompletedTask;
    }
}

為何粒紋使用邏輯識別碼

在物件導向的環境中 (例如 .NET),物件的身分識別很難從其參考來區別。 當物件使用 new 關鍵字建立時,傳回的參考代表其身分識別的各個層面,但將物件對應至其所代表的某些外部實體的部分除外。 Orleans 設計用於分散式系統。 在分散式系統中,物件參考無法代表執行個體身分識別,因為物件參考僅限於單一流程位址空間。 Orleans 會使用邏輯識別碼來避免這項限制。 粒紋使用邏輯識別碼,以便粒紋參考在流程存留期之間保持有效,並且可從一個流程移植到另一個流程,從而允許它們能夠儲存並在稍後擷取或透過網路傳送至應用程式中的另一個流程,同時仍參考相同的實體:為其建立參考的粒紋。