Service Fabric spawn actor при запуске
Есть ли способ требовать, чтобы система порождала определенных актеров при запуске.
В настоящее время я активирую набор актеров, которые мне нужны Program.cs
после регистрации актера.
Это работает нормально, но я иногда получаю ReminderLoadInProgressException
потому что активируемый субъект должен зарегистрировать напоминание, но не все напоминания были загружены в тот момент, когда он пытается это сделать.
Есть ли стандартный способ для посева кластера?
2 ответа
Нет, вам нужно что-то, чтобы активировать ваших актеров.
Program.cs - не лучшее место, чтобы сделать это, потому что его выполнение не соответствует жизненному циклу вашего сервиса, как вы, вероятно, заметили.
если вам нужно активировать некоторых актеров при запуске службы актеров, хорошее место для этого - метод RunAsync службы актеров. Вы можете настроить свой актерский сервис, написав сервис, производный от него, так же, как вы делаете, когда пишете сервис с состоянием:
РЕДАКТИРОВАТЬ: убедитесь, что вы звоните и ждите base.RunAsync() в первую очередь!
class MyActorService : ActorService
{
public MyActorService(StatefulServiceContext context, ActorTypeInformation typeInfo, Func<ActorBase> newActor)
: base(context, typeInfo, newActor)
{ }
protected async override Task RunAsync(CancellationToken cancellationToken)
{
await base.RunAsync(cancellationToken);
var proxy = ActorProxy.Create<IMyActor>(new ActorId(0));
await proxy.StartDoingStuff();
}
}
Затем зарегистрируйте службу актера, чтобы среда выполнения знала, как использовать ее для размещения экземпляров актера:
static class Program
{
private static void Main()
{
ActorRuntime.RegisterActorAsync<MyActor>(
(context, actorType) => new MyActorService(context, actorType, () => new MyActor()))
.GetAwaiter().GetResult();
Thread.Sleep(Timeout.Infinite);
}
}
Просто убедитесь, что метод субъекта является идемпотентом, потому что он будет выполняться каждый раз, когда запускается основная реплика службы субъекта (после отработки отказа, балансировки ресурсов, обновления приложения и т. Д.), Но приятно то, что он не будет выполняться до того, как Служба актера готова, и она всегда будет выполняться при запуске службы.
Смотрите здесь для получения дополнительной информации о том, как работать со службой актера: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-actors-platform/
Не могу комментировать, поэтому я размещаю комментарий здесь:
Для полноты картины: если ваш подкласс ActorService не имеет имени по умолчанию (из ServiceManifest.xml - например, вы динамически генерируете экземпляры службы), вам придется использовать двухпараметрическую перегрузку ActorProxy.Create, например:
var actor = ActorProxy.Create<IMyActor>(new ActorId(0), this.Context.ServiceName);
В противном случае вы получите исключение "Сервис не существует":
System.Fabric.FabricServiceNotFoundException: Service does not exist.
---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80071BCD at
System.Fabric.Interop.NativeClient.IFabricServiceManagementClient4
.EndResolveServicePartition(IFabricAsyncOperationContext context)
...