无法确认正在创建任何演员
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 的第一条消息的地方。
希望这对您有所帮助。