Статические объекты в актерах Service Fabric
Существует субъект фабрики услуг со следующим определением, который зарегистрирован, а затем незарегистрирован путем реализации IRemindable
интерфейс. У этого актера тоже есть статический словарь.
[StatePersistence(StatePersistence.None)]
[ActorService(Name = "ProcessorActorService")]
public class ProcessorActor : BaseActor, IRemindable
{
private static Dictionary<object,object> _myDictionary;
}
Насколько я понимаю, сервисная фабрика создает несколько экземпляров одного и того же актера, если у каждого актера во время создания экземпляра разные. Когда создается каждый экземпляр субъекта, действие напоминания добавляет объект в словарь для последующей обработки.
Мое ожидание / понимание было таким, что область действия словаря находится в том же самом экземпляре, но когда экземпляр следующего актера оживает, я понимаю, что _myDictionary
имеет узлы, которые были добавлены в другом актере! Таким образом, создается впечатление, что словарь является общим для всех живых экземпляров одного и того же типа актера! Это правильное понимание или тот же уже созданный актер снова вызывается?!
Поскольку актер реализует IRemindable
Я ожидаю, что GC удалит субъект из кластера после его отмены регистрации, но, похоже, этого не происходит. Возможно ли, что статический словарь заставит экземпляр актера остаться на месте?
2 ответа
Я думаю, что это больше проблема .Net, чем проблема Service Fabric. Насколько я помню, статические экземпляры собираются только после сбора AppDomain (обычно, когда процесс завершается).
Взгляните на " Основы сбора мусора", чтобы узнать, как и когда собирать экземпляры.
Что касается поддержания состояния, я предлагаю вам взглянуть на Введение в надежные субъекты Service Fabric, это может помочь вам достичь того, чего вы хотите.
Обновить
Также обратите внимание на управление состоянием Reliable Actors.
Надеюсь, поможет!
Насколько я понимаю, сервисная фабрика создает несколько экземпляров одного и того же актера, если у каждого актера во время создания экземпляра разные.
Это правильно. Каждый новый идентификатор генерирует новый экземпляр Actor.
Из документов:
Используйте модификатор static, чтобы объявить статический член, который принадлежит самому типу, а не конкретному объекту.
Когда вы объявляете private
static
Dictionary<object,object> _myDictionary;
как статический, вы говорите CLR, что поле принадлежит не экземпляру этого объекта, а определению типа, в этом случае оно генерирует единственный экземпляр, который принадлежит типу Actor, а не объекты, созданные и уничтоженные во время выполнения.
Правильный способ сохранить состояние актера - использовать менеджер состояний, например так:
[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
public MyActor(ActorService actorService, ActorId actorId)
: base(actorService, actorId)
{
}
public Task<int> GetCountAsync()
{
return this.StateManager.GetStateAsync<int>("MyState");
}
}
Документация объясняет это более подробно.