Не могу подтвердить, что актеры создаются - PullRequest
0 голосов
/ 26 июня 2019

В Service Fabric я пытаюсь вызвать ActorService и получить список всех актеров.Я не получаю никаких ошибок, но актеры не возвращаются.Это всегда ноль.

Вот как я добавляю актеров:

ActorProxy.Create<IUserActor>(
  new ActorId(uniqueName), 
  "fabric:/ECommerce/UserActorService");

И вот как я пытаюсь получить список всех актеров:

var proxy = ActorServiceProxy.Create(new Uri("fabric:/ECommerce/UserActorService"), 0);

ContinuationToken continuationToken = null;
CancellationToken cancellationToken = new CancellationTokenSource().Token;
List<ActorInformation> activeActors = new List<ActorInformation>();

do
{
  var proxy = GetUserActorServiceProxy();
  PagedResult<ActorInformation> page = await proxy.GetActorsAsync(continuationToken, cancellationToken);

  activeActors.AddRange(page.Items.Where(x => x.IsActive));

  continuationToken = page.ContinuationToken;
}
while (continuationToken != null);

Но независимо от того, сколькоПользователи, которых я добавил, у объекта страницы всегда будет ноль элементов.Что мне не хватает?

1 Ответ

1 голос
/ 28 июня 2019

Второй аргумент int в ActorServiceProxy.Create (Uri, int, string) - это ключ секции (вы можете узнать больше о разбиении субъекта здесь ).

Проблема в том, что ваш код проверяет только один раздел (partitionKey = 0).

Таким образом, решения довольно просты - вам нужно перебирать все разделы вашего сервиса. Вот ответ с примером кода для получения разделов и их перебора.

ОБНОВЛЕНИЕ 2019.07.01


Я не заметил этого с первого раза, но причина, по которой вы не возвращаете никаких актеров, заключается в том, что вы не создаете никаких актеров - вы создаете прокси!

Причиной такой путаницы является то, что акторы Service Fabric являются виртуальными, т. Е. С точки зрения пользователя, актер всегда существует, но в реальной жизни Service Fabric автоматически управляет временем жизни объекта субъекта и при необходимости восстанавливает его состояние.

Вот цитата из документации :

Актер активируется автоматически (вызывая создание объекта актера) при первой отправке сообщения на его идентификатор актера . Через какое-то время объект субъекта подвергается сборке мусора. В будущем повторное использование идентификатора актера приведет к созданию нового объекта актера. Состояние актера переживает время жизни объекта при сохранении в диспетчере состояний.

В вашем примере вы никогда не отправляете сообщения актерам!

Вот пример кода, который я написал в Program.cs недавно созданного проекта Actor:

// Please don't forget to replace "fabric:/Application16/Actor1ActorService" with your actor service name.

ActorRuntime.RegisterActorAsync<Actor1> (
  (context, actorType) => 
    new ActorService(context, actorType)).GetAwaiter().GetResult();

var actor = ActorProxy.Create<IActor1>(
  ActorId.CreateRandom(),
  new Uri("fabric:/Application16/Actor1ActorService"));

_ = actor.GetCountAsync(default).GetAwaiter().GetResult();

ContinuationToken continuationToken = null;
var activeActors = new List<ActorInformation>();

var serviceName = new Uri("fabric:/Application16/Actor1ActorService");
using (var client = new FabricClient())
{
  var partitions = client.QueryManager.GetPartitionListAsync(serviceName).GetAwaiter().GetResult();;

  foreach (var partition in partitions)
  {
    var pi = (Int64RangePartitionInformation) partition.PartitionInformation;
    var proxy = ActorServiceProxy.Create(new Uri("fabric:/Application16/Actor1ActorService"), pi.LowKey);
    var page = proxy.GetActorsAsync(continuationToken, default).GetAwaiter().GetResult();

    activeActors.AddRange(page.Items);

    continuationToken = page.ContinuationToken;
  }
}

Thread.Sleep(Timeout.Infinite);

Обратите особое внимание на строку:

_ = actor.GetCountAsync(default).GetAwaiter().GetResult();

Здесь отправляется первое сообщение актеру.


Надеюсь, это поможет.

...