[akka-persistence] Sending messages to a shard region with AtLeastOnce delivery

291 views
Skip to first unread message

dave....@threatstack.com

unread,
Jan 20, 2017, 9:39:46 AM1/20/17
to Akka User List
Hi All,

    Im using cluster sharding and I also have a use case for AtLeastOnce guaranteed message delivery (which of course requires persistence). The problem is that the deliver() method is not actually sending my messages to the shard region. Here's some code for the shard region:

val shardRegion = ClusterSharding(context.system).start(
  typeName = ShardName,
  entityProps = ShardEntity.props(appConfig),
  settings = ClusterShardingSettings(context.system),
  extractEntityId = ShardEntity.idExtractor,
  extractShardId = ShardEntity.shardResolver)

Here's the delivery code:

persist(Message(data)) { _ =>
// Is this the correct way to send
// persistent messages to shard region??
deliver(shardRegion.path) { deliveryId =>
MsgWithId(deliveryId, data)
}
}

For some reason, the shard region entities never see the messages from the call to deliver(). Am I doing something wrong?

Justin du coeur

unread,
Jan 20, 2017, 12:35:40 PM1/20/17
to akka...@googlegroups.com
Hmm.  Where is the deliver() method coming from?  Normally you send messages to sharded entities with the normal tell() method on the ShardRegion, same as any other Actor...

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+unsubscribe@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

dave....@threatstack.com

unread,
Jan 20, 2017, 2:57:36 PM1/20/17
to Akka User List
The deliver() method is part of the AtLeastOnceDelivery trait which is part of the persistence module (http://doc.akka.io/docs/akka/current/scala/persistence.html#At-Least-Once_Delivery). You use that method to provide a monotonically increasing delivery ID which can later be confirmed or retried. The deliver() method takes an actor path and you need to return a message that will ultimately be sent to the actor (in my case it's the actor ref to the shard region). 

On Friday, January 20, 2017 at 12:35:40 PM UTC-5, Justin du coeur wrote:
Hmm.  Where is the deliver() method coming from?  Normally you send messages to sharded entities with the normal tell() method on the ShardRegion, same as any other Actor...
On Fri, Jan 20, 2017 at 9:39 AM, <dave....@threatstack.com> wrote:
Hi All,

    Im using cluster sharding and I also have a use case for AtLeastOnce guaranteed message delivery (which of course requires persistence). The problem is that the deliver() method is not actually sending my messages to the shard region. Here's some code for the shard region:

val shardRegion = ClusterSharding(context.system).start(
  typeName = ShardName,
  entityProps = ShardEntity.props(appConfig),
  settings = ClusterShardingSettings(context.system),
  extractEntityId = ShardEntity.idExtractor,
  extractShardId = ShardEntity.shardResolver)

Here's the delivery code:

persist(Message(data)) { _ =>
// Is this the correct way to send
// persistent messages to shard region??
deliver(shardRegion.path) { deliveryId =>
MsgWithId(deliveryId, data)
}
}

For some reason, the shard region entities never see the messages from the call to deliver(). Am I doing something wrong?

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.

Justin du coeur

unread,
Jan 20, 2017, 5:31:40 PM1/20/17
to akka...@googlegroups.com
Ah, I see -- sorry, I'd missed that context.

I can't say I've used AtLeastOnceDelivery, but the code certainly *looks* reasonably straightforward.  It looks like it ought to work unless there is something wrong with sending to a ShardRegion via ActorSelection.  (Which is what is going on under the hood.)

What do your MsgWithId and ShardEntity classes look like?  Are you confident that idExtractor() and shardResolver() work correctly with MsgWithId?

To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+unsubscribe@googlegroups.com.

dave....@threatstack.com

unread,
Jan 21, 2017, 4:20:05 PM1/21/17
to Akka User List
So first off, well done Justin because you did nail the root cause! I figured out that I forgot to add the new classes to the shard and entity extractor functions. Those should really be defaulted to throw errors if the partial functions don't match the incoming message because they are silent failures. Im going to attempt a PR at defaulting the extractor functions to throw errors if you forget to define a function for a given type. 
Reply all
Reply to author
Forward
0 new messages