无法确认正在创建任何演员

Can't confirm any actors are being created

在 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);

但无论我添加了多少用户,页面对象的项目始终为零。我错过了什么?

ActorServiceProxy.Create(Uri, int, string) is the partition key (you can find out more about actor partitioning here 中的第二个参数 int).

这里的问题是您的代码只检查 一个 分区 (partitionKey = 0)。

因此解决方案非常简单 - 您必须遍历服务的所有分区。这是一个 ,其中包含用于获取分区并对其进行迭代的代码示例。

更新 2019.07.01


我第一次没有发现这一点,但您没有返回任何演员的原因是因为您没有创建任何演员 - 您正在创建代理!

造成这种混淆的原因是 Service Fabric actor 是虚拟的,即从用户的角度来看,actor 始终存在,但在现实生活中,Service Fabric 管理 actor 对象的生命周期,自动持久化并根据需要恢复其状态。

引用自documentation

An actor is automatically activated (causing an actor object to be constructed) the first time a message is sent to its actor ID. After some period of time, the actor object is garbage collected. In the future, using the actor ID again, causes a new actor object to be constructed. An actor's state outlives the object's lifetime when stored in the state manager.

在您的示例中,您从未向演员发送过任何消息!

这是我在新创建的 Actor 项目 Program.cs 中编写的代码示例:

// 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();

这里是发送给 actor 的第一条消息的地方。


希望这对您有所帮助。