I have a two node cluster using persistent actors with sharding. The nodes are exposed to the external world using AKKA HTTP routes. if I get a request for an entity to a node that is hosting its shard, I obviously get the data. However, if the request comes to the other node, I get an ask timeout. What is the best way to ensure I can access entity state regardless of the node that serves the HTTP request. The snippet below is how I initialize the entity reference.
val sharding = ClusterSharding(context.system)
sharding.init(Entity(typeKey = ShoppingCartActor.TypeKey) { entityContext =>
ShoppingCartActor(entityContext.entityId, PersistenceId(entityContext.entityTypeKey.name, entityContext.entityId))
})
val shoppingCartActor = sharding.entityRefFor(ShoppingCartActor.TypeKey, "Cart")
val routes = new ShopingCartRoute(shoppingCartActor)(context.system).routes
startHttpServer(routes, context.system)
I am still finding my way around the API. I can send a message to the ShardingRegion actor instead of the entity reference from any node to target the right entity instance. However, I am only able to do that using a tell (!), not sure how to do the same using an ask (?)
I am getting a timeout if I use the entity reference and the call comes to the node that is not hosting the entity. I thought that was expected behavior and the way to address it was to route the message using shard region. I can get it to behave in a location transparent way in the ping call using shard region. However, that uses tell. I want assItem, removeItem and viewCart to work the way ping works, but using ask pattern. Possibly, I am missing something quite fundamental.
I have slightly changed the code below. The tellShard call works as expected. But askShard method only works if an external request hits the node hosting the shard, on all other nodes it times out.
I have figured the issue. This was due to serialization failing on the reply. I added configuration to allow Java serialization and it works fine. Thank you.