package org.akka.essentials.actor; import static java.util.Arrays.asList; import org.akka.essentials.data.CalculationEvent; import org.akka.essentials.data.OperationCmd; import akka.japi.Procedure; import akka.persistence.SnapshotOffer; import akka.persistence.UntypedPersistentActor; public class CalculationActor extends UntypedPersistentActor { public String persistenceId() { return "calculator-1"; } private Integer state = Integer.valueOf(0); @Override public void onReceiveRecover(Object msg) { if (msg instanceof CalculationEvent) { // apply the operation message(s) when recovering the actor state calculate((CalculationEvent) msg); } else if (msg instanceof SnapshotOffer) { // apply the snapshot message to recover from an intermediate state state = Integer.valueOf((String) ((SnapshotOffer) msg).snapshot()); } else { unhandled(msg); } } @Override public void onReceiveCommand(Object msg) { if (msg instanceof OperationCmd) { final OperationCmd ops = (OperationCmd) msg; // read the event final CalculationEvent event = ops.getCalculationEvent(); persist(asList(event), new Procedure<CalculationEvent>() { public void apply(CalculationEvent event) throws Exception { // apply the operation on the state calculate(event); // save the operation message on the event stream getContext().system().eventStream().publish(event); } }); } else if (msg.equals("snap")) { // take an intermediate snapshot of the state. In case of recovery, // actor can use the // last saved snapshot and apply events post that. saveSnapshot(state.toString()); } else if (msg.equals("print")) { System.out.println(state); } else { // System.out.println("data corrupt"); unhandled(msg); } } private void calculate(CalculationEvent ops) { switch (ops.getOperator()) { case ADD: state = state + ops.getNumber(); break; case SUBTRACT: state = state - ops.getNumber(); break; case MULTIPLY: state = state * ops.getNumber(); break; case DIVIDE: state = state / ops.getNumber(); break; default: break; } } }