如何判断具有某个ActorId的Actor是否存在?
ActorProxy仅用于创建Actor。如果提供了不存在的Id,并且Actor不存在,则创建新的Actor。
标准的ActorService可以检索所有的Actors,但就我所知,它是关于它的。
答案 0 :(得分:4)
目前还没有简单的方法可以做到这一点。 Actors旨在抽象出对象实例的生命周期。只要你需要它就打电话给它,它会在那里。所以我不确定这是否真的需要。
也就是说,您可以创建另一种服务方法来迭代服务器端的所有actor,而不是将整个列表拉到客户端,但是如果你有数百万个actor实例,它就不会非常高效。
或者,您可以在actor的初始化期间存储标记状态,并查询状态提供程序,但代价是向actor添加更多状态和复制开销。
首先,创建一个服务接口:
public interface IActorServiceEx : IService
{
Task<bool> ActorExists(ActorId actorId, CancellationToken cancellationToken = default(CancellationToken));
}
然后,创建一个实现此接口的自定义actor服务:
internal class CustomActorService : ActorService, IActorServiceEx
{
public CustomActorService(StatefulServiceContext context, ActorTypeInformation actorTypeInfo, Func<ActorBase> actorFactory = null, IActorStateProvider stateProvider = null, ActorServiceSettings settings = null)
: base(context, actorTypeInfo, actorFactory, stateProvider, settings)
{
}
public async Task<bool> ActorExists(ActorId actorId, CancellationToken cancellationToken)
{
const int batchSize = 1000;
ContinuationToken token = null;
do
{
var actors = await StateProvider.GetActorsAsync(batchSize, token, cancellationToken);
if (actors.Items.Contains(actorId))
{
return true;
}
token = actors.ContinuationToken;
} while (token != null);
return false;
}
}
使用标记的备用版本:
internal class Actor1 : Actor, IActor1
{
protected override async Task OnActivateAsync()
{
await StateManager.TryAddStateAsync("Activated", true);
}
}
internal class CustomActorService : ActorService, IActorServiceEx
{
...
public Task<bool> ActorExists(ActorId actorId, CancellationToken cancellationToken)
{
return StateProvider.ContainsStateAsync(actorId, "Activated", cancellationToken);
}
}
最后,在注册演员时使用它,例如:
ActorRuntime.RegisterActorAsync<Actor1>((context, actorType) =>
new CustomActorService(context, actorType,
() => new Actor1())).GetAwaiter().GetResult();
并调用这种新的服务方法:
var actorService = ActorServiceProxy.Create<IActorServiceEx>(serviceUri, actorId);
var exists = await actorService.ActorExists(actorId);