简体   繁体   中英

Service Fabric spawn actor on startup

Is there a way to require the system to spawn certain actors on startup.

Currently I activate the set of actors that I need in Program.cs after the actor registration.

This is working ok, but I occasionally get a ReminderLoadInProgressException because the actor that is being activated needs to register a reminder but not all reminders have been loaded at the time it tries to do that.

Is there standard way to seed the cluster?

No, you need something to activate your actors.

Program.cs isn't the best place to do it because its execution doesn't really line up with your service's lifecycle, as you've probably noticed.

if you need to activate some actors when your actor service starts up, a good place to do that would be in the RunAsync method of your actor service. You can customize your actor service by writing a service that derives from it, same as you do when you write a stateful service:

EDIT: make sure you call and await base.RunAsync() first!

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();
    }
}

And then register your actor service so the runtime knows to use it to host your actor instances:

static class Program
{
    private static void Main()
    {
        ActorRuntime.RegisterActorAsync<MyActor>(
            (context, actorType) => new MyActorService(context, actorType, () => new MyActor()))
            .GetAwaiter().GetResult();

        Thread.Sleep(Timeout.Infinite);
    }
}

Just make sure that actor method is idempotent, because this will execute every time the primary replica of your actor service is started up (after failover, resource balancing, application upgrade, etc), but the nice thing is it won't execute before your actor service is ready and it will always execute when the service comes up.

See here for more info on how to work with the actor service: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-actors-platform/

Cannot comment so I'm putting the comment here:

For the sake of completeness: if your ActorService subclass does not have the default name (from the ServiceManifest.xml - for example you generate service instances dynamically), you will have to use the two-parameter ActorProxy.Create overload like this:

var actor = ActorProxy.Create<IMyActor>(new ActorId(0), this.Context.ServiceName);

Otherwise you would get "Service does not exist" exception:

System.Fabric.FabricServiceNotFoundException: Service does not exist. 
---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80071BCD at
System.Fabric.Interop.NativeClient.IFabricServiceManagementClient4
.EndResolveServicePartition(IFabricAsyncOperationContext context)
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM