无法确认正在创建任何演员
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 问题,但现在我已经准备好开始探索了。以上是关于无法确认正在创建任何演员的主要内容,如果未能解决你的问题,请参考以下文章
WPS 创建EXCEL对象失败,请确认已正确安装Excel程序?