I have some Akka 1.3 code which handles integration with an external messaging system which does not directly support the concept of replies. I’m attempting to upgrade the codebase to Akka 2.0 and am running into trouble because my existing design relies on simulating a “reply” mechanism by generating keys into a ConcurrentHashMap and using senderFuture for cleanup.
Messages being sent to the actor that’s handling dispatch may or may not be expecting replies, and even if they are expecting replies, after being sent across the wire, they may never get a reply. As a result, the HashMap should only store entries for messages that actually want a reply (asks, not tells), and it must have some form of cleanup mechanism to sweep out entries which never received a reply.
In Akka 1.3, I’m doing this by attaching to the senderFuture, so when the actor that sent the message times out and gives up on a reply, the corresponding entry in the HashMap is removed as well:
if (self.senderFuture().isDefined) {
pendingRequests.put(replyToKey, sender)
self.senderFuture().get.onComplete( f => {
pendingRequests.remove(replyToKey)
}
}
Since Akka 2.0 has removed accessibility to senderFuture, is there a clean way of handling this scenario? Or do I just need to create a cleanup process from scratch?
The precise feature you are looking for is not retained in Akka 2.x because
Using
senderFuturemeant that you made the choice of cleanup action a responsibility of the client actor. You can still do that by simply including this information in the message you send, instead of putting it into how the message was sent.One more thing to consider is the DeathWatch feature added in 2.0: you can signal that cleanup is desired and the target can then
context.watch()the sender of the request, cleaning up when the correspondingTerminatedmessage is received (triggered by the sender’s demise). Then the client could still use the ask pattern with an appropriate timeout, which communicates the timed loss of interest back to the serving actor.