Two different type Entity actors in AKKA Cluster Sharding - akka

How to create two different type actors in a single Akka Cluster.
ActorRef ShardRegion=ClusterSharding.get(ClusterSys).start("Test", Props.create(ShardActor.class), settings,new ShardMessageExtrater());
Here when we start e ShardRegion we define the class it take to create entity actor.
Can we use two type of actor class to create entity Actors?
Any other way?

Related

Is there a way to achieve service downgrade in akka cluster sharding?

I'm trying to build up an Akka cluster ShardRegion that might need to be downgraded in the production environment when a bug occurs. However, instead of unregistering it by calling
ClusterClientReceptionist.get(nodeActorSystem).unregisterService(shardRegion)
which will terminate the ShardRegion and its child actors after all messages are consumed before PoisonPill, my sharding child actors have their internal state and purposes that need to be accomplished. I need an elegant way to slowly downgrade the process with the ShardRegion to let any session in-between finish, e.g. any new message with a different EntityId will be sent elsewhere.
I haven't yet found any means to downgrade it or just simply stop any new sharding AkkaActor to prop up on the ShardRegion.Is this even achievable in Akka Cluster ShardRegion?
You can accomplish part of this by specifying a custom stopMessage. The shard region will send this command to the entity actors when they are to be passivated or rebalanced. The default is PoisonPill, but a custom one allows the entity actors to do whatever they need to do to shut down (they do need to eventually stop themselves in this scenario).
If you're triggering a rebalance, the messages to the shard will be buffered until all the active entities in that shard have stopped, which may qualify as "any new message with a different entity ID will be sent elsewhere". Note that messages which are being sent outside of cluster sharding (i.e. directly between entity actors) will still be delivered normally (until said entity actors stop).

ClusterSharding: How to stop all the actors in a cluster shard?

I am working with Akka and have used ClusterSharding for a usecase. For some reason I want to stop all the actors in the ClusterShard.
Can somene help me with a way of doing it?
There's no reliable way to do this.
The closest would be to get the state of the shard (check the "Inspecting cluster sharding state" sections in the docs for classic or typed cluster sharding), which will contain the set of active entity IDs in each shard as of some point in time (with possibly no guarantee that the point in time is the same for all shards). You can then use that set of entity IDs to send a message to each entity to passivate itself: each actor will need to implement that support itself (there's no equivalent of a PoisonPill which would work).
During all of this, there's no guarantee that more sharded entities haven't been started by cluster sharding, nor is there a guarantee that cluster sharding won't restart the entities you've stopped.

Akka Typed ActorSelection/Receptionist

I have question about ActorSelection/Receptionist in new Akka Typed.....
Before Akka Typed I didn't use ActorSelection because I read somewhere that it was not performant so I kept reference to the actor over HashMaps, now I am reading the documentation of the Akka Typed, I see that another mechanism Receptionist exist, so for me the question is, does it also suffers the same problems ActorSelection and I should stick to my old pattern of keeping reference to Actor over HashMap or now the receptionist is the way to go....
My specific scenario, my Actor spawns several Child Actors creates several Child Actors, if the parent Actor passivates or restored over Akka Persistence, it should again find reference to these Child Actors....
So what do you think, would I experience Performance problems if I convert to Receptionist?????
Thx for answers...
ActorSelection will resolve the actor path to an ActorRef each time you use it, this is somewhat costly, if used for a high throughput actor but has the upside that if the actor is stopped, and then later a new actor is started at the same path, the ActorSelection will deliver messages to the new actor, while if you had an ActorRef it specifically points to the actor instance that is no stopped and messages end up in dead letters.
The receptionist is quite different and is more like a registry of actors that you can subscribe to. When the set of ActorRefs registered for a key changes you get an update message with the new set, there is no extra overhead per message sent, you are dealing directly with the ActorRefs of the recipients.
Note that you can use the GroupRouter for delivery to actors registered with the receptionist and to avoid having to implement the subscription part in your actor.

Akka PersistenActor with RoundRobinPool

I am trying to implement eventsourcing using Akka persisten actors. The receiver actors are persistent, they persist the message before processing them. I have a round-robin-pool of persistent receiver actors. Now since the persistent id is same for these pool of actors, how to handle recovery? Or i want to understand the correct way of using persistency with pool of actors...
I was thinking to use this propery 'akka.persistence.max-concurrent-recoveries = 1'.
NOTE: i am using java
According to docs:
Note persistenceId must be unique to a given entity in the journal
(database table/keyspace). When replaying messages persisted to the
journal, you query messages with a persistenceId. So, if two different
entities share the same persistenceId, message-replaying behavior is
corrupted.
Seems that you need akka cluster-sharding with unique persistenceId for every entity actor.
Also see:
Can I Read/Write from separate actors with same PersistenceId?

What's the best way to get an ActorRef from a Cluster given a relative path?

I have an Akka application having several nodes in a cluster. Each node runs an assortment of different Actors, i.e. not all nodes are the same--there is some duplication for redundancy.
I've tried code like this to get a ref to communicate with an Actor on another node:
val myservice = context.actorSelection("akka.tcp://ClusterSystem#127.0.0.1:2552/user/myService")
This works, because there is an Actor named myService running on the node at that address. That feels like simple Akka Remoting though, not clustering, because the address is point-to-point.
I want to ask the cluster "Hey! Anybody out there have an ActorRef at path "/user/myService"?", and get back one or more refs (depending on how many redundant copies are out there). Then I could use that selector to communicate.
Consider using Cluster Sharding, which would remove the need to know exactly where in the cluster your actors are located:
Cluster sharding is useful when you need to distribute actors across several nodes in the cluster and want to be able to interact with them using their logical identifier, but without having to care about their physical location in the cluster, which might also change over time.
With Cluster Sharding, you don't need to know an actor's path. Instead, you interact with ShardRegion actors, which delegate messages to the appropriate node. For example:
val stoutRegion: ActorRef = ClusterSharding(system).shardRegion("Stout")
stoutRegion ! GetPint("guinness")
If you don't want to switch to cluster sharding but use your current deployment structure, you can use the ClusterReceptionist as described in the ClusterClient docs.
However, this way you would have to register the actors with the receptionist before they are discoverable to clients.