How do you know what messages you can send to an actor?

Is there a standard way to formalize my scala / akka actor? Imho, a situation where I need to examine an implementation to know what to send is actually not a very good option. Also, if the implementation has changed and my message is no longer valid (does not trigger the action that I think it is calling), then I don't get any warnings or errors.

+3


source to share


2 answers


This is a very debated issue in the community. I've heard that maybe Akka 3 will get better support for typical actors, but that's a while down the road.

In the meantime, you can use TypedActors , although the general suggestion is to use them within the confines of your application.

A good approach that doesn't give you any types of security but makes the actor's contract more visible is to define the messages that the actor can receive in its companion object. This way, every time you want to send a message to an actor, you select its companion object from the message. This, of course, works best if you have specific messages for each actor. If you change the implementation, you can remove the old message and add a new one so that anyone who wanted to use the old implementation will get compiler errors.



There was a nice template on the mailing list last week . It creates traits to define contracts for the actors and their consumers, but you still need to make sure the consumer mixes with the correct trait.

In my experience, the best way to make sure everything works is with an extensive suite of tests that will test each actor for itself, but also the communication between specific participants.

+5


source


The approach commonly used in Erlang is to not send messages directly to the process and to provide an additional API in the same module that defines the behavior of the process. In Akka it would look like

class Foo extends Actor {
  // handles messages Bar(x: Int) and Baz
}

object Foo {
  def bar(foo: ActorRef, x: Int) = foo ! Bar(x)

  def baz(foo: ActorRef) = (foo ? Baz).mapTo[TypeOfResponseToBaz]
}

      



One problem is handling returned messages, since Erlang generally maintains a more synchronous style than Akka. This can be handled by a naming convention (for example, BarResponse

or FooBarResponse

if different participants are processing the same message with different responses).

+1


source







All Articles