2

How can I initialize an Azure Service Fabric Actor on creation?

I've tried overloading actor constructor with initialization method and it didn't worked.

Must I call initialization method from client after creating the actor or there's a way to make actor initialize itself automaticaly when during creating?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Shkire
  • 25
  • 4

2 Answers2

2

An Actor is first created when you call a method on it. So if you need to initialize an Actor that does not exist yet, you'll need to make sure it becomes alive first. It can't do that by itself.

You could create a method to initialize the Actor and make it part of the Actor's interface.

You can also use the OnActivateAsync method which will trigger for every activation.

Read more about the Actor lifecycle here.

LoekD
  • 11,402
  • 17
  • 27
  • What I want to do is to call my "Initialize" custom method after creating the actor using ActorProxy. I tried it using constructor overload: `public MyActor(ActorService service, ActorId id) : base(service, id) { InitializeActor(); }` but it doesn't work. So the only way of call the "Initialize" method after actor creation is from outside the actor `IMyActor myActor = ActorProxy.Create("myActor"); myActor.InitializeActor();` or using the `OnActivateAsync` method, right? – Shkire Mar 01 '17 at 16:04
  • Calling it from the constructor should work. But the only way your constructor gets called is when the Actor is activated. And that happens by calling an operation on it. – LoekD Mar 02 '17 at 07:47
0

The Actor framework doesn't differentiate much between creating an Actor the first time and activating an Actor that has been deactivated and lies dormant. Both actions will create a new instance of the Actor implementation (calls .ctor) and then calls OnActivateAsync. It does this before it executes any method dispatched to the Actor. There is no means for you to create an instance of an Actor without calling a method on the Actor's interface, it is all part of the underlying ActorBase and ActorManager's handling of messages.

Also, slighlty depending on the type of persistence you have chosen for your actor (None, Volatile or Persisted), the ActorService hosting the Actor stores a persistence key with the IActorStateProvider associated with the Actor/ActorService. This is how the ActorService "knows" about it's actors as well. When you ask an ActorService about known Actors, it queries it's StateProvider for

If you want to run some Initialization code the first time, and only the first time an Actor is activated then you could add a state key for that Actor in OnActivateAsync:

    protected override async Task OnActivateAsync()
    {
        ActorEventSource.Current.ActorMessage(this, "Actor activated.");

        var initialized = await  this.StateManager.ContainsStateAsync("initalized");
        if (!initialized) await Initialize();
    }

    private async Task Initialize()
    {
        ActorEventSource.Current.ActorMessage(this, "Actor initialized.");

        await this.StateManager.AddStateAsync("initialized", true);
    }
yoape
  • 3,285
  • 1
  • 14
  • 27