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

时间:2019-06-26 15:32:14

标签: azure azure-service-fabric actor

在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 个答案:

答案 0 :(得分:1)

ActorServiceProxy.Create(Uri, int, string)中的第二个参数int是分区键(您可以了解更多有关actor分区here的信息)。

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

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

更新2019.07.01


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

产生这种混乱的原因是Service Fabric角色是虚拟的,即从用户的角度来看,actor始终存在,但在现实生活中,Service Fabric会自动维持actor对象的生存期,并根据需要恢复其状态。

这里是documentation的引文:

  

演员会自动激活(导致要构造演员对象)第一次将消息发送到演员ID的消息。一段时间后,actor对象将被垃圾回收。将来,再次使用actor ID,将导致构造新的actor对象。当存储在状态管理器中时,参与者的状态会超过对象的生命周期。

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

这是我在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();

这是发送给演员的第一条消息。


希望这会有所帮助。