简体   繁体   中英

Static objects in Service Fabric actors

There is a service fabric actor with the following definition which is registered and then unregistered by implementing IRemindable interface. This actor has a static dictionary too.

[StatePersistence(StatePersistence.None)]
[ActorService(Name = "ProcessorActorService")]
public class ProcessorActor : BaseActor, IRemindable
{
 private static Dictionary<object,object> _myDictionary;

}

My understanding is that service fabric creates multiple instances of the same actor if each actor's guid is different at instantiation time. When each actor instance is created the reminder's action adds an object to the dictionary for processing later on.

My expectation/understanding has been such that the dictionary's scope is within the same instantiated actor, but when the next actor's instance comes to life, I realize that the _myDictionary has the nodes that were added in another actor! So, it kind of gives the impression that the dictionary is shared among all live instances of the same actor type! Is that a correct understanding or the same already-instantiated actor is called again?!

Since the actor implements IRemindable I expect the GC to remove the actor from the cluster after unregistering it but it does not seem to be happening. Is it possible that the static dictionary causes the actor's instance to stick around?

I think it's more of a .Net issue than a Service Fabric issue. As far as I remember, static instances are only collected once the AppDomain is collected (usually when the process terminates).

Take a look at Fundamentals of Garbage Collection on how and when instances get collected.

Regarding how to maintain state, I suggest you take a look at Introduction to Service Fabric Reliable Actors , it might help you achieve what you want.

Update

Also, take a look at Reliable Actors state management .

Hope it helps!

My understanding is that service fabric creates multiple instances of the same actor if each actor's guid is different at instantiation time.

This is correct. Every new ID generates a new instance of the Actor.


From the docs :

Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object.

When you declare private static Dictionary<object,object> _myDictionary; as static you are telling to the CLR that the field does not belong to an instance of that object but to the type definition, in this case it generates a single instance that belongs to the Actor type and not the the objects created and destroyed by the runtime.

The correct way to save the actor state is using the state manager, like this:

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
  public MyActor(ActorService actorService, ActorId actorId)
    : base(actorService, actorId)
  {
  }

  public Task<int> GetCountAsync()
  {
    return this.StateManager.GetStateAsync<int>("MyState");
  }
} 

The documentation explains it in more details.

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