Удостоверений зерна

Orleans В каждом из них есть один, уникальный, определяемый пользователем идентификатор, состоящий из двух частей:

  1. Имя типа зерна, которое однозначно идентифицирует класс зерна.
  2. Ключ зерна, который однозначно идентифицирует логический экземпляр этого класса зерна.

Тип зерна и ключ представлены как строки, доступные Orleans для чтения человеком, и, по соглашению, удостоверение зерна записывается с типом зерна и ключом, разделенным символом / . Например, shoppingcart/bob65 представляет тип зерна с именем shoppingcart ключа bob65.

Это не обычно для создания удостоверений зерна напрямую. Вместо этого чаще создаются ссылки на зерна с помощью Orleans.IGrainFactory.

В следующих разделах подробно рассматриваются имена типов зерна и ключи зерна.

Имена типов зерна

Orleans создает имя типа зерна для вас на основе класса реализации зерна, удалив суффикс "Grain" из имени класса, если он присутствует, и преобразовав итоговую строку в его нижнее представление. Например, для класса будет ShoppingCartGrain присвоено имя shoppingcartтипа зерна. Рекомендуется, чтобы имена и ключи типа зерна состояли только из печатных символов, таких как буквенно-числовые (a-z,ZA- и90-) символы и символы, такие как -, _, . =@ Другие символы могут или не поддерживаются и часто требуют специального лечения при печати в журналах или в виде идентификаторов в других системах, таких как базы данных.

Кроме того, Orleans.GrainTypeAttribute атрибут можно использовать для настройки имени типа зерна для класса зерна, к которому он присоединен, как показано в следующем примере:

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

В предыдущем примере класс ShoppingCartGrain зерна имеет имя cartтипа зерна. Каждое зерно может иметь только одно имя типа зерна.

Для универсальных зерен универсальный arity должен быть включен в имя типа зерна. Например, рассмотрим следующий DictionaryGrain<K, V> класс:

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

Класс зерна имеет два универсальных параметра, поэтому обратная строка`, за которой следует универсальный arity, 2, добавляется в конец имени типа зерна, чтобы создать имя dict`2типа зерна, dict как указано в атрибуте класса зерна. [GrainType("dict`2")]

Ключи зерна

Для удобства предоставляет методы, Orleans которые позволяют создавать ключи зерна из a Guid или a Int64, а также String. Первичный ключ область к типу зерна. Таким образом, полное удостоверение зерна формируется из типа зерна и его ключа.

Вызывающий элемент зерна решает, какую схему следует использовать. Доступные параметры:

Так как базовые данные одинаковы, схемы можно использовать взаимозаменяемо: они все кодируются в виде строк.

Ситуации, требующие однотонного экземпляра зерна, могут использовать известное фиксированное значение, например "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 или длинной и строки для ссылки на зерно.

Вы можете наследовать интерфейс от IGrainWithGuidCompoundKey или IGrainWithIntegerCompoundKey интерфейса следующим образом:

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 использует логические идентификаторы, чтобы избежать этого ограничения. С помощью логических идентификаторов используются ссылки на зерна в течение всего времени существования процесса и переносятся из одного процесса в другой, что позволяет хранить их и позже извлекать или отправляться по сети в другой процесс в приложении, все время ссылаясь на ту же сущность: зерно, для которого была создана ссылка.