0
votes

I am writing a program that has to interact with a library that was implemented using Akka. In detail, this library exposes an Actor as endpoint.

As far as I know and as it is explained in the book Applied Akka Pattern, the best way to interact with an Actor system from the outside is using the Ask Pattern.

The library I have to use exposes an actor Main that accepts a Create message. In response to this message, it can respond with two different messages to the caller, CreateAck and CreateNack(error).

The code I am using is more or less the following.

implicit val timeout = Timeout(5 seconds)
def create() = (mainActor ? Create).mapTo[???]

The problem is clearly that I do not know which kind of type I have to use in mapTo function, instead of ???.

Am I using the right approach? Is there any other useful pattern to access to an Actor System from an outside program that does not use Actors?

2

2 Answers

2
votes

In general it's best to leave Actors to talk between Actors, you'd simply receive a response then - simple.

If you indeed have to integrate them with the "outside", the ask pattern is fine indeed. Please note though that if you're doing this inside an Actor, this perhaps isn't the best way to go about it.

If there's a number of unrelated response types I'd suggest:

(1) Make such common type; this can be as simple as :

sealed trait CreationResponse
final case object CreatedThing extends CreationResponse
final case class FailedCreationOfThing(t: Throwable) extends CreationResponse
final case class SomethingElse...(...) extends CreationResponse

which makes the protocol understandable, and trackable. I recommend this as it's explicit and helps in understanding what's going on.

(2) For completely unrelated types simply collecting over the future would work by the way, without doing the mapTo:

val res: Future[...] = (bob ? CreateThing) collect { 
  case t: ThatWorked => t // or transform it
  case nope: Nope    => nope // or transform it to a different value
}

This would work fine type wise if the results, t and nope have a common super type, that type would then be the ... in the result Future. If a message comes back and does not match any case it'd be a match error; you could add a case _ => whatever then for example, OR it would point to a programming error.

0
votes

See if CreateAck or CreateNack(error) inherit from any sort of class or object. If thats the case you can use the parent class or object in the .mapTo[CreateResultType].

Another solution is to use .mapTo[Any] and use a match case to find the resulting type.