influx6 / actorkit

Simple yet powerful actor model in golang for message passing based applications [Work in Progress]
MIT License
20 stars 2 forks source link

Grain Actors: Distributed Materialized Actors #1

Closed influx6 closed 5 years ago

influx6 commented 5 years ago

Grain Actors

Taking inspiration from the concepts found in Orleans, we would like to create Grains and Grain Clusters in Actorkit using a technique which borrows communication over pubsub/message-queue technologies as communication plane.

MasterGrain Actor

The job of said actor is to receive grain orchestration messages from underline actor system or communication plane (message queus like Google PubSub, NATS, ..etc) or from local actors in the design to lunch a set of actors which exists for the processing of certain types of messages. What differs in this Grain actors is that they are materialized actors. They do not exists at the point of instantiation of giving actor system but are generated by the MasterGrain which must be instantiated at runtime. This requires said actor system to have all the necessarily pieces to create such actor types, which will require the implementation of a Behavior registries which will be initialized with the MasterGrain actor to use in creation of giving actor types for specific message types processing.

Message Queues

To bring the system into full circle we will require implementation of different messaging system based actors that allows usage of this type of grain system on different infrastructure. Target queues:

ServiceNames

With actorkit unlike Orleans, grains are created using string names of giving action or service. The GUID of a generated grain simply represents the location of where it is currently deployed to or called from. The GUID may change over a period of time depending on if giving grain was relocated to another cluster due to the death of the previous. The idea is unlike a local actor system without grains, the notion of a the actors address is relatively cheap and replaceable, hence only the action name or service name is of most importance.

Usually the service name should be something like Users.AddEmail or Contacts.GetContacts or Contacts.AddContract.. etc. This grains should be very specific and should not be too generalist. This way even if a given grain is the child of another, it's address becomes the generalist reference to it. In essence, build your actors for example Users to have child actors that handle specific pieces like AddEmail, UpdateContact. This is not a set rule in stone, and can be diverted to just use a single actor User to handle such cases with specific service address pointing to it. But it is far simpler using the previously mentioned approach, as it makes more sense when we are generating actors to handle some operation specific to a type and action.

A difference with Orleans is we do not actively kill grains running on a giving cluster/server. The idea is that the exists for processing till they die or are unable to be restarted for work anymore and hence get terminated.

Also, we do not necessarily follow all of Orleans approaches, but only keep the idea that a giving actor can be materialized on any cluster depending on the availability of the behavior in that clusters registry, which provides us a very perfect way of handling cluster based segregation, which means we intentionally only provide to a cluster during compilation and runtime the behaviors which will ever run on that cluster and nothing more, this way, a cluster can not instantiate a behavior it knows nothing about, which means we can create or segregate certain behaviors to certain servers and only if that server is gone down, should we need to consider spinning up a new cluster to replace that server with set behaviors available to new cluster. (Note might not be a good idea for resilience though unless the cluster creation after the death of a previous one is blazing fast).

influx6 commented 5 years ago

Complicated.