Sharding entity custom Stop msg and HashCodeNoEnvelopeMsgExtractor

It seems that it is not possible to use custom Stop message together with HashCodeNoEnvelopeMessageExtractor:


sealed trait Message {
    def mpId: String
}

case class Stop() extends Message {
  def mpId: String = throw new UnsupportedOperationException()
}

Entity(MyEntity.typeKey("MyEntity")) { entityCtx =>
  MyEntity.behavior(entityCtx) 
}
.withStopMessage(Stop())
.withMessageExtractor(new HashCodeNoEnvelopeMessageExtractor[Message](config.numberOfShards) {
        def entityId(message: Message): String = message.mpId
})


java.lang.UnsupportedOperationException: null
	at MyEntityProtocol$Stop.mpId(MyEntity.scala:21)
	at MyService$$anon$1.entityId(MyService.scala:37)
	at MyService$$anon$1.entityId(MyService.scala:36)
	at akka.cluster.sharding.typed.internal.ExtractorAdapter.entityId(ClusterShardingImpl.scala:58)
	at akka.cluster.sharding.typed.internal.ClusterShardingImpl$$anonfun$1.isDefinedAt(ClusterShardingImpl.scala:168)
	at akka.cluster.sharding.ShardRegion$$anonfun$receive$2.applyOrElse(ShardRegion.scala:731)

I ended up passing invalid Stop("") msg instance to withStopMessage method just to test manual passivation.

Hmm, yeah, tricky corner case, but can’t think of a way around this somewhat awkward logic when not using envelopes.

The stop message is not actually ever sent between nodes, so does not need an entity id to be directed to, it is sent by the local shard to one of its children, but since it must be a part of the sharded actor protocol you can easily end up like this.

Thanks for the explanation. I suppose it would be beneficial to add this explanation to the docs.

Good suggestion!

1 Like