pekko/akka-docs/rst/java/code/docs/persistence/PersistenceDocTest.java

173 lines
6 KiB
Java
Raw Normal View History

akka-persistence prototype The most prominent changes compared to eventsourced are: - No central processor and channel registry any more - Auto-recovery of processors on start and restart (can be disabled) - Recovery of processor networks doesn't require coordination - Explicit channel activation not needed any more - Message sequence numbers generated per processor (no gaps) - Sender references are journaled along with messages - Processors can determine their recovery status - No custom API on extension object, only messages - Journal created by extension from config, not by application - Applications only interact with processors and channels via messages - Internal design prepared for having processor-specific journal actors (for later optimization possibilities) Further additions and changes during review: - Allow processor implementation classes to use inherited stash - Channel support to resolve (potentially invalid) sender references - Logical intead of physical deletion of messages - Pinned dispatcher for LevelDB journal - Processor can handle failures during recovery - Message renamed to Persistent This prototype has the following limitations: - Serialization of persistent messages and their payload via JavaSerializer only (will be configurable later) - The LevelDB journal implementation based on a LevelDB Java port, not the native LevelDB (will be configurable later) The following features will be added later using separate tickets: - Snapshot-based recovery - Reliable channels - Journal plugin API - Optimizations - ...
2013-09-14 14:19:18 +02:00
package docs.persistence;
import scala.Option;
import akka.actor.*;
import akka.persistence.*;
public class PersistenceDocTest {
public interface ProcessorMethods {
//#processor-id
public String processorId();
//#processor-id
//#recovery-status
public boolean recoveryRunning();
public boolean recoveryFinished();
//#recovery-status
//#current-message
public Persistent getCurrentPersistentMessage();
//#current-message
}
static Object o1 = new Object() {
//#definition
class MyProcessor extends UntypedProcessor {
public void onReceive(Object message) throws Exception {
if (message instanceof Persistent) {
// message has been written to journal
Persistent persistent = (Persistent)message;
Object payload = persistent.payload();
Long sequenceNr = persistent.sequenceNr();
// ...
} else {
// message has not been written to journal
}
}
}
//#definition
class MyActor extends UntypedActor {
ActorRef processor;
public MyActor() {
//#usage
processor = getContext().actorOf(Props.create(MyProcessor.class), "myProcessor");
processor.tell(Persistent.create("foo"), null);
processor.tell("bar", null);
//#usage
}
public void onReceive(Object message) throws Exception {
// ...
}
private void recover() {
//#recover-explicit
processor.tell(Recover.create(), null);
//#recover-explicit
}
}
};
static Object o2 = new Object() {
abstract class MyProcessor1 extends UntypedProcessor {
//#recover-on-start-disabled
@Override
public void preStartProcessor() {}
//#recover-on-start-disabled
//#recover-on-restart-disabled
@Override
public void preRestartProcessor(Throwable reason, Option<Object> message) {}
//#recover-on-restart-disabled
}
abstract class MyProcessor2 extends UntypedProcessor {
//#recover-on-start-custom
@Override
public void preStartProcessor() {
getSelf().tell(Recover.create(457L), null);
}
//#recover-on-start-custom
}
abstract class MyProcessor3 extends UntypedProcessor {
//#deletion
@Override
public void preRestartProcessor(Throwable reason, Option<Object> message) throws Exception {
if (message.isDefined() && message.get() instanceof Persistent) {
delete((Persistent) message.get());
}
super.preRestartProcessor(reason, message);
}
//#deletion
}
class MyProcessor4 extends UntypedProcessor implements ProcessorMethods {
//#processor-id-override
@Override
public String processorId() {
return "my-stable-processor-id";
}
//#processor-id-override
@Override
public void onReceive(Object message) throws Exception {}
}
};
static Object o3 = new Object() {
//#channel-example
class MyProcessor extends UntypedProcessor {
private final ActorRef destination;
private final ActorRef channel;
public MyProcessor() {
this.destination = getContext().actorOf(Props.create(MyDestination.class));
this.channel = getContext().actorOf(Channel.props(), "myChannel");
}
public void onReceive(Object message) throws Exception {
if (message instanceof Persistent) {
Persistent p = (Persistent)message;
Persistent out = p.withPayload("done " + p.payload());
channel.tell(Deliver.create(out, destination), getSelf());
}
}
}
class MyDestination extends UntypedActor {
public void onReceive(Object message) throws Exception {
if (message instanceof Persistent) {
Persistent p = (Persistent)message;
System.out.println("received " + p.payload());
p.confirm();
}
}
}
//#channel-example
class MyProcessor2 extends UntypedProcessor {
private final ActorRef destination;
private final ActorRef channel;
public MyProcessor2(ActorRef destination) {
this.destination = getContext().actorOf(Props.create(MyDestination.class));
//#channel-id-override
this.channel = getContext().actorOf(Channel.props("my-stable-channel-id"));
//#channel-id-override
}
public void onReceive(Object message) throws Exception {
if (message instanceof Persistent) {
Persistent p = (Persistent)message;
Persistent out = p.withPayload("done " + p.payload());
channel.tell(Deliver.create(out, destination), getSelf());
//#channel-example-reply
channel.tell(Deliver.create(out, getSender()), getSelf());
//#channel-example-reply
//#resolve-destination
channel.tell(Deliver.create(out, getSender(), Resolve.destination()), getSelf());
//#resolve-destination
//#resolve-sender
channel.tell(Deliver.create(out, destination, Resolve.sender()), getSender());
//#resolve-sender
}
}
}
};
}