javaakkaakka-persistence

Akka classic - sending custom class message types


I'm attempting to follow best practices for sending messages between Akka actors and reading the following :

https://github.com/akka/akka/blob/v2.6.15/akka-docs/src/test/java/jdocs/actor/ActorDocTest.java#L101-L129

https://doc.akka.io/docs/akka/current/actors.html

It seems best practice is to define a static class that contains the message to be sent.

From reading the docs I've defined the following :

import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.persistence.AbstractPersistentActor;

class RecoveryActor extends AbstractPersistentActor {

    public static class Msg1 {}
    public static class Msg2 {}

    private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);

    /**
     * Handler that will be called on recovery.
     * @return
     */
    @Override
    public Receive createReceiveRecover() {
        return receiveBuilder()
                .match(Msg1.class, this::receiveMsg1)
                .match(Msg2.class, this::receiveMsg2)
                .build();
    }

    private void receiveMsg1(Msg1 msg) {
        log.info("in receive message 1");
    }

    private void receiveMsg2(Msg2 msg) {
        log.info("in receive message 2");
    }

    /**
     * The normal receive method.
     * @return
     */
    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .match(String.class, s -> s.equals("cmd"), s -> persist("evt", this::handleEvent))
                .build();
    }

    private void handleEvent(String event) {
        System.out.println("in handle event");
    }

    @Override
    public String persistenceId() {
        return "simple-accountant"; //best practice, the id should be unique.
    }

}

But I'm unsure how to send messages using the Msg1 and Msg2

I've defined a new class to send a message :

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;

public class ActorMessaging {

    public static void main(String args[]){
        final ActorSystem system = ActorSystem.create("example");
        final ActorRef actor = system.actorOf(Props.create(RecoveryActor.class));

        actor.tell(RecoveryActor.Msg1);

    }
}

But it fails with compiler error :

java: cannot find symbol
  symbol:   variable Msg1
  location: class recoverydemo.RecoveryActor

How can I send messages to the Actor of type Msg1?

Is this best practice for sending messages between actors, wrapping the messages in a custom class ?


Solution

  • Silly mistake on my part. I overrode the incorrect method. I should have overridden createReceive instead :

        public Receive createReceive() {
    
            return receiveBuilder()
                    .match(RecoveryActor.Msg1.class, this::receiveMsg1)
                    .match(Msg2.class, this::receiveMsg2)
                    .build();
            
    //        return receiveBuilder()
    //                .match(String.class, s -> s.equals("cmd"), s -> persist("evt", this::handleEvent))
    //                .build();
        }