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

Posted

技术标签:

【中文标题】无法确认正在创建任何演员【英文标题】:Can't confirm any actors are being created 【发布时间】:2019-11-08 14:40:27 【问题描述】:

在 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】:

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

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

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

更新 2019.07.01


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

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

这是documentation的引述:

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

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

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

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


希望这会有所帮助。

【讨论】:

感谢您抽出宝贵时间!但我看不出该代码如何产生任何影响。首先,我只有一个分区。其次,它对每个分区做同样的事情。它使用低键作为分区键,每个分区都一样吗? 另外,我在您链接的代码中看到 Create 方法使用 IMyService 类型。这是必要的还是它也适用于 IActorService?因为我的 ActorService 还没有自己的服务类型。无论如何,我遍历了分区,但没有返回任何内容。它是空的。在尝试列出之前,我确保添加了三个演员。 OMFG!这真太了不起了。当然。所以实际上我应该认为演员是不持久的。只有他们的状态是持久的。因此,如果我不将状态分配给某个 ID,则不会保存任何内容。如果一个 ID 有一个状态,那么就会保存关于那个演员的元数据。正确的?我今晚会试试这个。 成功了!谢谢你教我这个基础。在接下来的几周内,我肯定会在这里发布更多 SF 问题,但现在我已经准备好开始探索了。

以上是关于无法确认正在创建任何演员的主要内容,如果未能解决你的问题,请参考以下文章

创建EXCEL对象失败,请确认已正确安装Excel程序?

WPS 创建EXCEL对象失败,请确认已正确安装Excel程序?

Android smack 服务器收据确认

Kibana 显示“正在搜索...”,没有显示任何结果。 ElasticSearch 中存在已确认的数据

jQuery确认对话模式 - 无法成功提交表单

mac 无法打开xx ,因为无法确认开发者身份