+per #20257 Snapshots with PersistentFSM
This commit is contained in:
parent
86f54e8719
commit
68e479a050
9 changed files with 1043 additions and 29 deletions
|
|
@ -789,6 +789,18 @@ Here is how everything is wired together:
|
||||||
|
|
||||||
.. includecode:: ../../../akka-persistence/src/test/java/akka/persistence/fsm/AbstractPersistentFSMTest.java#customer-apply-event
|
.. includecode:: ../../../akka-persistence/src/test/java/akka/persistence/fsm/AbstractPersistentFSMTest.java#customer-apply-event
|
||||||
|
|
||||||
|
``andThen`` can be used to define actions which will be executed following event's persistence - convenient for "side effects" like sending a message or logging.
|
||||||
|
Notice that actions defined in ``andThen`` block are not executed on recovery:
|
||||||
|
|
||||||
|
.. includecode:: ../../../akka-persistence/src/test/java/akka/persistence/fsm/AbstractPersistentFSMTest.java#customer-andthen-example
|
||||||
|
|
||||||
|
A snapshot of state data can be persisted by calling the ``saveStateSnapshot()`` method:
|
||||||
|
|
||||||
|
.. includecode:: ../../../akka-persistence/src/test/java/akka/persistence/fsm/AbstractPersistentFSMTest.java#customer-snapshot-example
|
||||||
|
|
||||||
|
On recovery state data is initialized according to the latest available snapshot, then the remaining domain events are replayed, triggering the
|
||||||
|
``applyEvent`` method.
|
||||||
|
|
||||||
Storage plugins
|
Storage plugins
|
||||||
===============
|
===============
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -796,6 +796,18 @@ Here is how everything is wired together:
|
||||||
|
|
||||||
.. includecode:: ../../../akka-persistence/src/test/scala/akka/persistence/fsm/PersistentFSMSpec.scala#customer-apply-event
|
.. includecode:: ../../../akka-persistence/src/test/scala/akka/persistence/fsm/PersistentFSMSpec.scala#customer-apply-event
|
||||||
|
|
||||||
|
``andThen`` can be used to define actions which will be executed following event's persistence - convenient for "side effects" like sending a message or logging.
|
||||||
|
Notice that actions defined in ``andThen`` block are not executed on recovery:
|
||||||
|
|
||||||
|
.. includecode:: ../../../akka-persistence/src/test/scala/akka/persistence/fsm/PersistentFSMSpec.scala#customer-andthen-example
|
||||||
|
|
||||||
|
A snapshot of state data can be persisted by calling the ``saveStateSnapshot()`` method:
|
||||||
|
|
||||||
|
.. includecode:: ../../../akka-persistence/src/test/scala/akka/persistence/fsm/PersistentFSMSpec.scala#customer-snapshot-example
|
||||||
|
|
||||||
|
On recovery state data is initialized according to the latest available snapshot, then the remaining domain events are replayed, triggering the
|
||||||
|
``applyEvent`` method.
|
||||||
|
|
||||||
.. _storage-plugins:
|
.. _storage-plugins:
|
||||||
|
|
||||||
Storage plugins
|
Storage plugins
|
||||||
|
|
|
||||||
|
|
@ -4293,6 +4293,16 @@ public final class MessageFormats {
|
||||||
*/
|
*/
|
||||||
akka.protobuf.ByteString
|
akka.protobuf.ByteString
|
||||||
getTimeoutBytes();
|
getTimeoutBytes();
|
||||||
|
|
||||||
|
// optional int64 timeoutNanos = 3;
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
boolean hasTimeoutNanos();
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
long getTimeoutNanos();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Protobuf type {@code PersistentStateChangeEvent}
|
* Protobuf type {@code PersistentStateChangeEvent}
|
||||||
|
|
@ -4355,6 +4365,11 @@ public final class MessageFormats {
|
||||||
timeout_ = input.readBytes();
|
timeout_ = input.readBytes();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 24: {
|
||||||
|
bitField0_ |= 0x00000004;
|
||||||
|
timeoutNanos_ = input.readInt64();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (akka.protobuf.InvalidProtocolBufferException e) {
|
} catch (akka.protobuf.InvalidProtocolBufferException e) {
|
||||||
|
|
@ -4481,9 +4496,26 @@ public final class MessageFormats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optional int64 timeoutNanos = 3;
|
||||||
|
public static final int TIMEOUTNANOS_FIELD_NUMBER = 3;
|
||||||
|
private long timeoutNanos_;
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public boolean hasTimeoutNanos() {
|
||||||
|
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public long getTimeoutNanos() {
|
||||||
|
return timeoutNanos_;
|
||||||
|
}
|
||||||
|
|
||||||
private void initFields() {
|
private void initFields() {
|
||||||
stateIdentifier_ = "";
|
stateIdentifier_ = "";
|
||||||
timeout_ = "";
|
timeout_ = "";
|
||||||
|
timeoutNanos_ = 0L;
|
||||||
}
|
}
|
||||||
private byte memoizedIsInitialized = -1;
|
private byte memoizedIsInitialized = -1;
|
||||||
public final boolean isInitialized() {
|
public final boolean isInitialized() {
|
||||||
|
|
@ -4507,6 +4539,9 @@ public final class MessageFormats {
|
||||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||||
output.writeBytes(2, getTimeoutBytes());
|
output.writeBytes(2, getTimeoutBytes());
|
||||||
}
|
}
|
||||||
|
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||||
|
output.writeInt64(3, timeoutNanos_);
|
||||||
|
}
|
||||||
getUnknownFields().writeTo(output);
|
getUnknownFields().writeTo(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4524,6 +4559,10 @@ public final class MessageFormats {
|
||||||
size += akka.protobuf.CodedOutputStream
|
size += akka.protobuf.CodedOutputStream
|
||||||
.computeBytesSize(2, getTimeoutBytes());
|
.computeBytesSize(2, getTimeoutBytes());
|
||||||
}
|
}
|
||||||
|
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||||
|
size += akka.protobuf.CodedOutputStream
|
||||||
|
.computeInt64Size(3, timeoutNanos_);
|
||||||
|
}
|
||||||
size += getUnknownFields().getSerializedSize();
|
size += getUnknownFields().getSerializedSize();
|
||||||
memoizedSerializedSize = size;
|
memoizedSerializedSize = size;
|
||||||
return size;
|
return size;
|
||||||
|
|
@ -4644,6 +4683,8 @@ public final class MessageFormats {
|
||||||
bitField0_ = (bitField0_ & ~0x00000001);
|
bitField0_ = (bitField0_ & ~0x00000001);
|
||||||
timeout_ = "";
|
timeout_ = "";
|
||||||
bitField0_ = (bitField0_ & ~0x00000002);
|
bitField0_ = (bitField0_ & ~0x00000002);
|
||||||
|
timeoutNanos_ = 0L;
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000004);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4680,6 +4721,10 @@ public final class MessageFormats {
|
||||||
to_bitField0_ |= 0x00000002;
|
to_bitField0_ |= 0x00000002;
|
||||||
}
|
}
|
||||||
result.timeout_ = timeout_;
|
result.timeout_ = timeout_;
|
||||||
|
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
|
||||||
|
to_bitField0_ |= 0x00000004;
|
||||||
|
}
|
||||||
|
result.timeoutNanos_ = timeoutNanos_;
|
||||||
result.bitField0_ = to_bitField0_;
|
result.bitField0_ = to_bitField0_;
|
||||||
onBuilt();
|
onBuilt();
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -4706,6 +4751,9 @@ public final class MessageFormats {
|
||||||
timeout_ = other.timeout_;
|
timeout_ = other.timeout_;
|
||||||
onChanged();
|
onChanged();
|
||||||
}
|
}
|
||||||
|
if (other.hasTimeoutNanos()) {
|
||||||
|
setTimeoutNanos(other.getTimeoutNanos());
|
||||||
|
}
|
||||||
this.mergeUnknownFields(other.getUnknownFields());
|
this.mergeUnknownFields(other.getUnknownFields());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -4885,6 +4933,39 @@ public final class MessageFormats {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optional int64 timeoutNanos = 3;
|
||||||
|
private long timeoutNanos_ ;
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public boolean hasTimeoutNanos() {
|
||||||
|
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public long getTimeoutNanos() {
|
||||||
|
return timeoutNanos_;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public Builder setTimeoutNanos(long value) {
|
||||||
|
bitField0_ |= 0x00000004;
|
||||||
|
timeoutNanos_ = value;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public Builder clearTimeoutNanos() {
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000004);
|
||||||
|
timeoutNanos_ = 0L;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// @@protoc_insertion_point(builder_scope:PersistentStateChangeEvent)
|
// @@protoc_insertion_point(builder_scope:PersistentStateChangeEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4896,6 +4977,774 @@ public final class MessageFormats {
|
||||||
// @@protoc_insertion_point(class_scope:PersistentStateChangeEvent)
|
// @@protoc_insertion_point(class_scope:PersistentStateChangeEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface PersistentFSMSnapshotOrBuilder
|
||||||
|
extends akka.protobuf.MessageOrBuilder {
|
||||||
|
|
||||||
|
// required string stateIdentifier = 1;
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
boolean hasStateIdentifier();
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
java.lang.String getStateIdentifier();
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
akka.protobuf.ByteString
|
||||||
|
getStateIdentifierBytes();
|
||||||
|
|
||||||
|
// required .PersistentPayload data = 2;
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
boolean hasData();
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentPayload getData();
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentPayloadOrBuilder getDataOrBuilder();
|
||||||
|
|
||||||
|
// optional int64 timeoutNanos = 3;
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
boolean hasTimeoutNanos();
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
long getTimeoutNanos();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Protobuf type {@code PersistentFSMSnapshot}
|
||||||
|
*/
|
||||||
|
public static final class PersistentFSMSnapshot extends
|
||||||
|
akka.protobuf.GeneratedMessage
|
||||||
|
implements PersistentFSMSnapshotOrBuilder {
|
||||||
|
// Use PersistentFSMSnapshot.newBuilder() to construct.
|
||||||
|
private PersistentFSMSnapshot(akka.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||||
|
super(builder);
|
||||||
|
this.unknownFields = builder.getUnknownFields();
|
||||||
|
}
|
||||||
|
private PersistentFSMSnapshot(boolean noInit) { this.unknownFields = akka.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||||
|
|
||||||
|
private static final PersistentFSMSnapshot defaultInstance;
|
||||||
|
public static PersistentFSMSnapshot getDefaultInstance() {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersistentFSMSnapshot getDefaultInstanceForType() {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final akka.protobuf.UnknownFieldSet unknownFields;
|
||||||
|
@java.lang.Override
|
||||||
|
public final akka.protobuf.UnknownFieldSet
|
||||||
|
getUnknownFields() {
|
||||||
|
return this.unknownFields;
|
||||||
|
}
|
||||||
|
private PersistentFSMSnapshot(
|
||||||
|
akka.protobuf.CodedInputStream input,
|
||||||
|
akka.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws akka.protobuf.InvalidProtocolBufferException {
|
||||||
|
initFields();
|
||||||
|
int mutable_bitField0_ = 0;
|
||||||
|
akka.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||||
|
akka.protobuf.UnknownFieldSet.newBuilder();
|
||||||
|
try {
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int tag = input.readTag();
|
||||||
|
switch (tag) {
|
||||||
|
case 0:
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
if (!parseUnknownField(input, unknownFields,
|
||||||
|
extensionRegistry, tag)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 10: {
|
||||||
|
bitField0_ |= 0x00000001;
|
||||||
|
stateIdentifier_ = input.readBytes();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 18: {
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentPayload.Builder subBuilder = null;
|
||||||
|
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||||
|
subBuilder = data_.toBuilder();
|
||||||
|
}
|
||||||
|
data_ = input.readMessage(akka.persistence.serialization.MessageFormats.PersistentPayload.PARSER, extensionRegistry);
|
||||||
|
if (subBuilder != null) {
|
||||||
|
subBuilder.mergeFrom(data_);
|
||||||
|
data_ = subBuilder.buildPartial();
|
||||||
|
}
|
||||||
|
bitField0_ |= 0x00000002;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 24: {
|
||||||
|
bitField0_ |= 0x00000004;
|
||||||
|
timeoutNanos_ = input.readInt64();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (akka.protobuf.InvalidProtocolBufferException e) {
|
||||||
|
throw e.setUnfinishedMessage(this);
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
throw new akka.protobuf.InvalidProtocolBufferException(
|
||||||
|
e.getMessage()).setUnfinishedMessage(this);
|
||||||
|
} finally {
|
||||||
|
this.unknownFields = unknownFields.build();
|
||||||
|
makeExtensionsImmutable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static final akka.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return akka.persistence.serialization.MessageFormats.internal_static_PersistentFSMSnapshot_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected akka.protobuf.GeneratedMessage.FieldAccessorTable
|
||||||
|
internalGetFieldAccessorTable() {
|
||||||
|
return akka.persistence.serialization.MessageFormats.internal_static_PersistentFSMSnapshot_fieldAccessorTable
|
||||||
|
.ensureFieldAccessorsInitialized(
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot.class, akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot.Builder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static akka.protobuf.Parser<PersistentFSMSnapshot> PARSER =
|
||||||
|
new akka.protobuf.AbstractParser<PersistentFSMSnapshot>() {
|
||||||
|
public PersistentFSMSnapshot parsePartialFrom(
|
||||||
|
akka.protobuf.CodedInputStream input,
|
||||||
|
akka.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws akka.protobuf.InvalidProtocolBufferException {
|
||||||
|
return new PersistentFSMSnapshot(input, extensionRegistry);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public akka.protobuf.Parser<PersistentFSMSnapshot> getParserForType() {
|
||||||
|
return PARSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int bitField0_;
|
||||||
|
// required string stateIdentifier = 1;
|
||||||
|
public static final int STATEIDENTIFIER_FIELD_NUMBER = 1;
|
||||||
|
private java.lang.Object stateIdentifier_;
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
public boolean hasStateIdentifier() {
|
||||||
|
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
public java.lang.String getStateIdentifier() {
|
||||||
|
java.lang.Object ref = stateIdentifier_;
|
||||||
|
if (ref instanceof java.lang.String) {
|
||||||
|
return (java.lang.String) ref;
|
||||||
|
} else {
|
||||||
|
akka.protobuf.ByteString bs =
|
||||||
|
(akka.protobuf.ByteString) ref;
|
||||||
|
java.lang.String s = bs.toStringUtf8();
|
||||||
|
if (bs.isValidUtf8()) {
|
||||||
|
stateIdentifier_ = s;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
public akka.protobuf.ByteString
|
||||||
|
getStateIdentifierBytes() {
|
||||||
|
java.lang.Object ref = stateIdentifier_;
|
||||||
|
if (ref instanceof java.lang.String) {
|
||||||
|
akka.protobuf.ByteString b =
|
||||||
|
akka.protobuf.ByteString.copyFromUtf8(
|
||||||
|
(java.lang.String) ref);
|
||||||
|
stateIdentifier_ = b;
|
||||||
|
return b;
|
||||||
|
} else {
|
||||||
|
return (akka.protobuf.ByteString) ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// required .PersistentPayload data = 2;
|
||||||
|
public static final int DATA_FIELD_NUMBER = 2;
|
||||||
|
private akka.persistence.serialization.MessageFormats.PersistentPayload data_;
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
public boolean hasData() {
|
||||||
|
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
public akka.persistence.serialization.MessageFormats.PersistentPayload getData() {
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
public akka.persistence.serialization.MessageFormats.PersistentPayloadOrBuilder getDataOrBuilder() {
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optional int64 timeoutNanos = 3;
|
||||||
|
public static final int TIMEOUTNANOS_FIELD_NUMBER = 3;
|
||||||
|
private long timeoutNanos_;
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public boolean hasTimeoutNanos() {
|
||||||
|
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public long getTimeoutNanos() {
|
||||||
|
return timeoutNanos_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initFields() {
|
||||||
|
stateIdentifier_ = "";
|
||||||
|
data_ = akka.persistence.serialization.MessageFormats.PersistentPayload.getDefaultInstance();
|
||||||
|
timeoutNanos_ = 0L;
|
||||||
|
}
|
||||||
|
private byte memoizedIsInitialized = -1;
|
||||||
|
public final boolean isInitialized() {
|
||||||
|
byte isInitialized = memoizedIsInitialized;
|
||||||
|
if (isInitialized != -1) return isInitialized == 1;
|
||||||
|
|
||||||
|
if (!hasStateIdentifier()) {
|
||||||
|
memoizedIsInitialized = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!hasData()) {
|
||||||
|
memoizedIsInitialized = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getData().isInitialized()) {
|
||||||
|
memoizedIsInitialized = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memoizedIsInitialized = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeTo(akka.protobuf.CodedOutputStream output)
|
||||||
|
throws java.io.IOException {
|
||||||
|
getSerializedSize();
|
||||||
|
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||||
|
output.writeBytes(1, getStateIdentifierBytes());
|
||||||
|
}
|
||||||
|
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||||
|
output.writeMessage(2, data_);
|
||||||
|
}
|
||||||
|
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||||
|
output.writeInt64(3, timeoutNanos_);
|
||||||
|
}
|
||||||
|
getUnknownFields().writeTo(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int memoizedSerializedSize = -1;
|
||||||
|
public int getSerializedSize() {
|
||||||
|
int size = memoizedSerializedSize;
|
||||||
|
if (size != -1) return size;
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||||
|
size += akka.protobuf.CodedOutputStream
|
||||||
|
.computeBytesSize(1, getStateIdentifierBytes());
|
||||||
|
}
|
||||||
|
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||||
|
size += akka.protobuf.CodedOutputStream
|
||||||
|
.computeMessageSize(2, data_);
|
||||||
|
}
|
||||||
|
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||||
|
size += akka.protobuf.CodedOutputStream
|
||||||
|
.computeInt64Size(3, timeoutNanos_);
|
||||||
|
}
|
||||||
|
size += getUnknownFields().getSerializedSize();
|
||||||
|
memoizedSerializedSize = size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 0L;
|
||||||
|
@java.lang.Override
|
||||||
|
protected java.lang.Object writeReplace()
|
||||||
|
throws java.io.ObjectStreamException {
|
||||||
|
return super.writeReplace();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot parseFrom(
|
||||||
|
akka.protobuf.ByteString data)
|
||||||
|
throws akka.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot parseFrom(
|
||||||
|
akka.protobuf.ByteString data,
|
||||||
|
akka.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws akka.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot parseFrom(byte[] data)
|
||||||
|
throws akka.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot parseFrom(
|
||||||
|
byte[] data,
|
||||||
|
akka.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws akka.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot parseFrom(java.io.InputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseFrom(input);
|
||||||
|
}
|
||||||
|
public static akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot parseFrom(
|
||||||
|
java.io.InputStream input,
|
||||||
|
akka.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseFrom(input, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot parseDelimitedFrom(java.io.InputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseDelimitedFrom(input);
|
||||||
|
}
|
||||||
|
public static akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot parseDelimitedFrom(
|
||||||
|
java.io.InputStream input,
|
||||||
|
akka.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseDelimitedFrom(input, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot parseFrom(
|
||||||
|
akka.protobuf.CodedInputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseFrom(input);
|
||||||
|
}
|
||||||
|
public static akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot parseFrom(
|
||||||
|
akka.protobuf.CodedInputStream input,
|
||||||
|
akka.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseFrom(input, extensionRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder newBuilder() { return Builder.create(); }
|
||||||
|
public Builder newBuilderForType() { return newBuilder(); }
|
||||||
|
public static Builder newBuilder(akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot prototype) {
|
||||||
|
return newBuilder().mergeFrom(prototype);
|
||||||
|
}
|
||||||
|
public Builder toBuilder() { return newBuilder(this); }
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
protected Builder newBuilderForType(
|
||||||
|
akka.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||||
|
Builder builder = new Builder(parent);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Protobuf type {@code PersistentFSMSnapshot}
|
||||||
|
*/
|
||||||
|
public static final class Builder extends
|
||||||
|
akka.protobuf.GeneratedMessage.Builder<Builder>
|
||||||
|
implements akka.persistence.serialization.MessageFormats.PersistentFSMSnapshotOrBuilder {
|
||||||
|
public static final akka.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return akka.persistence.serialization.MessageFormats.internal_static_PersistentFSMSnapshot_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected akka.protobuf.GeneratedMessage.FieldAccessorTable
|
||||||
|
internalGetFieldAccessorTable() {
|
||||||
|
return akka.persistence.serialization.MessageFormats.internal_static_PersistentFSMSnapshot_fieldAccessorTable
|
||||||
|
.ensureFieldAccessorsInitialized(
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot.class, akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot.Builder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct using akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot.newBuilder()
|
||||||
|
private Builder() {
|
||||||
|
maybeForceBuilderInitialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(
|
||||||
|
akka.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||||
|
super(parent);
|
||||||
|
maybeForceBuilderInitialization();
|
||||||
|
}
|
||||||
|
private void maybeForceBuilderInitialization() {
|
||||||
|
if (akka.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
|
||||||
|
getDataFieldBuilder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static Builder create() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder clear() {
|
||||||
|
super.clear();
|
||||||
|
stateIdentifier_ = "";
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000001);
|
||||||
|
if (dataBuilder_ == null) {
|
||||||
|
data_ = akka.persistence.serialization.MessageFormats.PersistentPayload.getDefaultInstance();
|
||||||
|
} else {
|
||||||
|
dataBuilder_.clear();
|
||||||
|
}
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000002);
|
||||||
|
timeoutNanos_ = 0L;
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000004);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder clone() {
|
||||||
|
return create().mergeFrom(buildPartial());
|
||||||
|
}
|
||||||
|
|
||||||
|
public akka.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptorForType() {
|
||||||
|
return akka.persistence.serialization.MessageFormats.internal_static_PersistentFSMSnapshot_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot getDefaultInstanceForType() {
|
||||||
|
return akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot.getDefaultInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot build() {
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot result = buildPartial();
|
||||||
|
if (!result.isInitialized()) {
|
||||||
|
throw newUninitializedMessageException(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot buildPartial() {
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot result = new akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot(this);
|
||||||
|
int from_bitField0_ = bitField0_;
|
||||||
|
int to_bitField0_ = 0;
|
||||||
|
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
|
||||||
|
to_bitField0_ |= 0x00000001;
|
||||||
|
}
|
||||||
|
result.stateIdentifier_ = stateIdentifier_;
|
||||||
|
if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
|
||||||
|
to_bitField0_ |= 0x00000002;
|
||||||
|
}
|
||||||
|
if (dataBuilder_ == null) {
|
||||||
|
result.data_ = data_;
|
||||||
|
} else {
|
||||||
|
result.data_ = dataBuilder_.build();
|
||||||
|
}
|
||||||
|
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
|
||||||
|
to_bitField0_ |= 0x00000004;
|
||||||
|
}
|
||||||
|
result.timeoutNanos_ = timeoutNanos_;
|
||||||
|
result.bitField0_ = to_bitField0_;
|
||||||
|
onBuilt();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder mergeFrom(akka.protobuf.Message other) {
|
||||||
|
if (other instanceof akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot) {
|
||||||
|
return mergeFrom((akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot)other);
|
||||||
|
} else {
|
||||||
|
super.mergeFrom(other);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder mergeFrom(akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot other) {
|
||||||
|
if (other == akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot.getDefaultInstance()) return this;
|
||||||
|
if (other.hasStateIdentifier()) {
|
||||||
|
bitField0_ |= 0x00000001;
|
||||||
|
stateIdentifier_ = other.stateIdentifier_;
|
||||||
|
onChanged();
|
||||||
|
}
|
||||||
|
if (other.hasData()) {
|
||||||
|
mergeData(other.getData());
|
||||||
|
}
|
||||||
|
if (other.hasTimeoutNanos()) {
|
||||||
|
setTimeoutNanos(other.getTimeoutNanos());
|
||||||
|
}
|
||||||
|
this.mergeUnknownFields(other.getUnknownFields());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean isInitialized() {
|
||||||
|
if (!hasStateIdentifier()) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!hasData()) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getData().isInitialized()) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder mergeFrom(
|
||||||
|
akka.protobuf.CodedInputStream input,
|
||||||
|
akka.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot parsedMessage = null;
|
||||||
|
try {
|
||||||
|
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||||
|
} catch (akka.protobuf.InvalidProtocolBufferException e) {
|
||||||
|
parsedMessage = (akka.persistence.serialization.MessageFormats.PersistentFSMSnapshot) e.getUnfinishedMessage();
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
if (parsedMessage != null) {
|
||||||
|
mergeFrom(parsedMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
private int bitField0_;
|
||||||
|
|
||||||
|
// required string stateIdentifier = 1;
|
||||||
|
private java.lang.Object stateIdentifier_ = "";
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
public boolean hasStateIdentifier() {
|
||||||
|
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
public java.lang.String getStateIdentifier() {
|
||||||
|
java.lang.Object ref = stateIdentifier_;
|
||||||
|
if (!(ref instanceof java.lang.String)) {
|
||||||
|
java.lang.String s = ((akka.protobuf.ByteString) ref)
|
||||||
|
.toStringUtf8();
|
||||||
|
stateIdentifier_ = s;
|
||||||
|
return s;
|
||||||
|
} else {
|
||||||
|
return (java.lang.String) ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
public akka.protobuf.ByteString
|
||||||
|
getStateIdentifierBytes() {
|
||||||
|
java.lang.Object ref = stateIdentifier_;
|
||||||
|
if (ref instanceof String) {
|
||||||
|
akka.protobuf.ByteString b =
|
||||||
|
akka.protobuf.ByteString.copyFromUtf8(
|
||||||
|
(java.lang.String) ref);
|
||||||
|
stateIdentifier_ = b;
|
||||||
|
return b;
|
||||||
|
} else {
|
||||||
|
return (akka.protobuf.ByteString) ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
public Builder setStateIdentifier(
|
||||||
|
java.lang.String value) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
bitField0_ |= 0x00000001;
|
||||||
|
stateIdentifier_ = value;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
public Builder clearStateIdentifier() {
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000001);
|
||||||
|
stateIdentifier_ = getDefaultInstance().getStateIdentifier();
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required string stateIdentifier = 1;</code>
|
||||||
|
*/
|
||||||
|
public Builder setStateIdentifierBytes(
|
||||||
|
akka.protobuf.ByteString value) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
bitField0_ |= 0x00000001;
|
||||||
|
stateIdentifier_ = value;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// required .PersistentPayload data = 2;
|
||||||
|
private akka.persistence.serialization.MessageFormats.PersistentPayload data_ = akka.persistence.serialization.MessageFormats.PersistentPayload.getDefaultInstance();
|
||||||
|
private akka.protobuf.SingleFieldBuilder<
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentPayload, akka.persistence.serialization.MessageFormats.PersistentPayload.Builder, akka.persistence.serialization.MessageFormats.PersistentPayloadOrBuilder> dataBuilder_;
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
public boolean hasData() {
|
||||||
|
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
public akka.persistence.serialization.MessageFormats.PersistentPayload getData() {
|
||||||
|
if (dataBuilder_ == null) {
|
||||||
|
return data_;
|
||||||
|
} else {
|
||||||
|
return dataBuilder_.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
public Builder setData(akka.persistence.serialization.MessageFormats.PersistentPayload value) {
|
||||||
|
if (dataBuilder_ == null) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
data_ = value;
|
||||||
|
onChanged();
|
||||||
|
} else {
|
||||||
|
dataBuilder_.setMessage(value);
|
||||||
|
}
|
||||||
|
bitField0_ |= 0x00000002;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
public Builder setData(
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentPayload.Builder builderForValue) {
|
||||||
|
if (dataBuilder_ == null) {
|
||||||
|
data_ = builderForValue.build();
|
||||||
|
onChanged();
|
||||||
|
} else {
|
||||||
|
dataBuilder_.setMessage(builderForValue.build());
|
||||||
|
}
|
||||||
|
bitField0_ |= 0x00000002;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
public Builder mergeData(akka.persistence.serialization.MessageFormats.PersistentPayload value) {
|
||||||
|
if (dataBuilder_ == null) {
|
||||||
|
if (((bitField0_ & 0x00000002) == 0x00000002) &&
|
||||||
|
data_ != akka.persistence.serialization.MessageFormats.PersistentPayload.getDefaultInstance()) {
|
||||||
|
data_ =
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentPayload.newBuilder(data_).mergeFrom(value).buildPartial();
|
||||||
|
} else {
|
||||||
|
data_ = value;
|
||||||
|
}
|
||||||
|
onChanged();
|
||||||
|
} else {
|
||||||
|
dataBuilder_.mergeFrom(value);
|
||||||
|
}
|
||||||
|
bitField0_ |= 0x00000002;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
public Builder clearData() {
|
||||||
|
if (dataBuilder_ == null) {
|
||||||
|
data_ = akka.persistence.serialization.MessageFormats.PersistentPayload.getDefaultInstance();
|
||||||
|
onChanged();
|
||||||
|
} else {
|
||||||
|
dataBuilder_.clear();
|
||||||
|
}
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000002);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
public akka.persistence.serialization.MessageFormats.PersistentPayload.Builder getDataBuilder() {
|
||||||
|
bitField0_ |= 0x00000002;
|
||||||
|
onChanged();
|
||||||
|
return getDataFieldBuilder().getBuilder();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
public akka.persistence.serialization.MessageFormats.PersistentPayloadOrBuilder getDataOrBuilder() {
|
||||||
|
if (dataBuilder_ != null) {
|
||||||
|
return dataBuilder_.getMessageOrBuilder();
|
||||||
|
} else {
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required .PersistentPayload data = 2;</code>
|
||||||
|
*/
|
||||||
|
private akka.protobuf.SingleFieldBuilder<
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentPayload, akka.persistence.serialization.MessageFormats.PersistentPayload.Builder, akka.persistence.serialization.MessageFormats.PersistentPayloadOrBuilder>
|
||||||
|
getDataFieldBuilder() {
|
||||||
|
if (dataBuilder_ == null) {
|
||||||
|
dataBuilder_ = new akka.protobuf.SingleFieldBuilder<
|
||||||
|
akka.persistence.serialization.MessageFormats.PersistentPayload, akka.persistence.serialization.MessageFormats.PersistentPayload.Builder, akka.persistence.serialization.MessageFormats.PersistentPayloadOrBuilder>(
|
||||||
|
data_,
|
||||||
|
getParentForChildren(),
|
||||||
|
isClean());
|
||||||
|
data_ = null;
|
||||||
|
}
|
||||||
|
return dataBuilder_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optional int64 timeoutNanos = 3;
|
||||||
|
private long timeoutNanos_ ;
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public boolean hasTimeoutNanos() {
|
||||||
|
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public long getTimeoutNanos() {
|
||||||
|
return timeoutNanos_;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public Builder setTimeoutNanos(long value) {
|
||||||
|
bitField0_ |= 0x00000004;
|
||||||
|
timeoutNanos_ = value;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional int64 timeoutNanos = 3;</code>
|
||||||
|
*/
|
||||||
|
public Builder clearTimeoutNanos() {
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000004);
|
||||||
|
timeoutNanos_ = 0L;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(builder_scope:PersistentFSMSnapshot)
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
defaultInstance = new PersistentFSMSnapshot(true);
|
||||||
|
defaultInstance.initFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(class_scope:PersistentFSMSnapshot)
|
||||||
|
}
|
||||||
|
|
||||||
private static akka.protobuf.Descriptors.Descriptor
|
private static akka.protobuf.Descriptors.Descriptor
|
||||||
internal_static_PersistentMessage_descriptor;
|
internal_static_PersistentMessage_descriptor;
|
||||||
private static
|
private static
|
||||||
|
|
@ -4926,6 +5775,11 @@ public final class MessageFormats {
|
||||||
private static
|
private static
|
||||||
akka.protobuf.GeneratedMessage.FieldAccessorTable
|
akka.protobuf.GeneratedMessage.FieldAccessorTable
|
||||||
internal_static_PersistentStateChangeEvent_fieldAccessorTable;
|
internal_static_PersistentStateChangeEvent_fieldAccessorTable;
|
||||||
|
private static akka.protobuf.Descriptors.Descriptor
|
||||||
|
internal_static_PersistentFSMSnapshot_descriptor;
|
||||||
|
private static
|
||||||
|
akka.protobuf.GeneratedMessage.FieldAccessorTable
|
||||||
|
internal_static_PersistentFSMSnapshot_fieldAccessorTable;
|
||||||
|
|
||||||
public static akka.protobuf.Descriptors.FileDescriptor
|
public static akka.protobuf.Descriptors.FileDescriptor
|
||||||
getDescriptor() {
|
getDescriptor() {
|
||||||
|
|
@ -4949,10 +5803,13 @@ public final class MessageFormats {
|
||||||
"verySnapshot.UnconfirmedDelivery\032c\n\023Unco" +
|
"verySnapshot.UnconfirmedDelivery\032c\n\023Unco" +
|
||||||
"nfirmedDelivery\022\022\n\ndeliveryId\030\001 \002(\003\022\023\n\013d" +
|
"nfirmedDelivery\022\022\n\ndeliveryId\030\001 \002(\003\022\023\n\013d" +
|
||||||
"estination\030\002 \002(\t\022#\n\007payload\030\003 \002(\0132\022.Pers" +
|
"estination\030\002 \002(\t\022#\n\007payload\030\003 \002(\0132\022.Pers" +
|
||||||
"istentPayload\"F\n\032PersistentStateChangeEv" +
|
"istentPayload\"\\\n\032PersistentStateChangeEv" +
|
||||||
"ent\022\027\n\017stateIdentifier\030\001 \002(\t\022\017\n\007timeout\030" +
|
"ent\022\027\n\017stateIdentifier\030\001 \002(\t\022\017\n\007timeout\030" +
|
||||||
"\002 \001(\tB\"\n\036akka.persistence.serializationH" +
|
"\002 \001(\t\022\024\n\014timeoutNanos\030\003 \001(\003\"h\n\025Persisten" +
|
||||||
"\001"
|
"tFSMSnapshot\022\027\n\017stateIdentifier\030\001 \002(\t\022 \n" +
|
||||||
|
"\004data\030\002 \002(\0132\022.PersistentPayload\022\024\n\014timeo" +
|
||||||
|
"utNanos\030\003 \001(\003B\"\n\036akka.persistence.serial",
|
||||||
|
"izationH\001"
|
||||||
};
|
};
|
||||||
akka.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
akka.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||||
new akka.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
new akka.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||||
|
|
@ -4994,7 +5851,13 @@ public final class MessageFormats {
|
||||||
internal_static_PersistentStateChangeEvent_fieldAccessorTable = new
|
internal_static_PersistentStateChangeEvent_fieldAccessorTable = new
|
||||||
akka.protobuf.GeneratedMessage.FieldAccessorTable(
|
akka.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||||
internal_static_PersistentStateChangeEvent_descriptor,
|
internal_static_PersistentStateChangeEvent_descriptor,
|
||||||
new java.lang.String[] { "StateIdentifier", "Timeout", });
|
new java.lang.String[] { "StateIdentifier", "Timeout", "TimeoutNanos", });
|
||||||
|
internal_static_PersistentFSMSnapshot_descriptor =
|
||||||
|
getDescriptor().getMessageTypes().get(5);
|
||||||
|
internal_static_PersistentFSMSnapshot_fieldAccessorTable = new
|
||||||
|
akka.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||||
|
internal_static_PersistentFSMSnapshot_descriptor,
|
||||||
|
new java.lang.String[] { "StateIdentifier", "Data", "TimeoutNanos", });
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -43,5 +43,12 @@ message AtLeastOnceDeliverySnapshot {
|
||||||
|
|
||||||
message PersistentStateChangeEvent {
|
message PersistentStateChangeEvent {
|
||||||
required string stateIdentifier = 1;
|
required string stateIdentifier = 1;
|
||||||
optional string timeout = 2;
|
optional string timeout = 2; //not used in new records from 2.4.5
|
||||||
|
optional int64 timeoutNanos = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PersistentFSMSnapshot {
|
||||||
|
required string stateIdentifier = 1;
|
||||||
|
required PersistentPayload data = 2;
|
||||||
|
optional int64 timeoutNanos = 3;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@
|
||||||
package akka.persistence.fsm
|
package akka.persistence.fsm
|
||||||
|
|
||||||
import akka.actor._
|
import akka.actor._
|
||||||
import akka.persistence.fsm.PersistentFSM.{ FSMState }
|
import akka.persistence.fsm.PersistentFSM.FSMState
|
||||||
import akka.persistence.serialization.Message
|
import akka.persistence.serialization.Message
|
||||||
import akka.persistence.{ PersistentActor, RecoveryCompleted }
|
import akka.persistence.{ PersistentActor, RecoveryCompleted, SnapshotOffer }
|
||||||
|
|
||||||
import scala.annotation.varargs
|
import scala.annotation.varargs
|
||||||
import scala.collection.immutable
|
import scala.collection.immutable
|
||||||
|
|
@ -48,6 +48,11 @@ trait PersistentFSM[S <: FSMState, D, E] extends PersistentActor with Persistent
|
||||||
*/
|
*/
|
||||||
lazy val statesMap: Map[String, S] = stateNames.map(name ⇒ (name.identifier, name)).toMap
|
lazy val statesMap: Map[String, S] = stateNames.map(name ⇒ (name.identifier, name)).toMap
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timeout set for the current state. Used when saving a snapshot
|
||||||
|
*/
|
||||||
|
private var currentStateTimeout: Option[FiniteDuration] = None
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override this handler to define the action on Domain Event
|
* Override this handler to define the action on Domain Event
|
||||||
*
|
*
|
||||||
|
|
@ -62,6 +67,13 @@ trait PersistentFSM[S <: FSMState, D, E] extends PersistentActor with Persistent
|
||||||
*/
|
*/
|
||||||
def onRecoveryCompleted(): Unit = {}
|
def onRecoveryCompleted(): Unit = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the current state as a snapshot
|
||||||
|
*/
|
||||||
|
final def saveStateSnapshot(): Unit = {
|
||||||
|
saveSnapshot(PersistentFSMSnapshot(stateName.identifier, stateData, currentStateTimeout))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After recovery events are handled as in usual FSM actor
|
* After recovery events are handled as in usual FSM actor
|
||||||
*/
|
*/
|
||||||
|
|
@ -75,6 +87,7 @@ trait PersistentFSM[S <: FSMState, D, E] extends PersistentActor with Persistent
|
||||||
override def receiveRecover: Receive = {
|
override def receiveRecover: Receive = {
|
||||||
case domainEventTag(event) ⇒ startWith(stateName, applyEvent(event, stateData))
|
case domainEventTag(event) ⇒ startWith(stateName, applyEvent(event, stateData))
|
||||||
case StateChangeEvent(stateIdentifier, timeout) ⇒ startWith(statesMap(stateIdentifier), stateData, timeout)
|
case StateChangeEvent(stateIdentifier, timeout) ⇒ startWith(statesMap(stateIdentifier), stateData, timeout)
|
||||||
|
case SnapshotOffer(_, PersistentFSMSnapshot(stateIdentifier, data: D, timeout)) => startWith(statesMap(stateIdentifier), data, timeout)
|
||||||
case RecoveryCompleted ⇒
|
case RecoveryCompleted ⇒
|
||||||
initialize()
|
initialize()
|
||||||
onRecoveryCompleted()
|
onRecoveryCompleted()
|
||||||
|
|
@ -103,6 +116,7 @@ trait PersistentFSM[S <: FSMState, D, E] extends PersistentActor with Persistent
|
||||||
handlersExecutedCounter += 1
|
handlersExecutedCounter += 1
|
||||||
if (handlersExecutedCounter == eventsToPersist.size) {
|
if (handlersExecutedCounter == eventsToPersist.size) {
|
||||||
super.applyState(nextState using nextData)
|
super.applyState(nextState using nextData)
|
||||||
|
currentStateTimeout = nextState.timeout
|
||||||
nextState.afterTransitionDo(stateData)
|
nextState.afterTransitionDo(stateData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -132,6 +146,16 @@ object PersistentFSM {
|
||||||
*/
|
*/
|
||||||
private[persistence] case class StateChangeEvent(stateIdentifier: String, timeout: Option[FiniteDuration]) extends PersistentFsmEvent
|
private[persistence] case class StateChangeEvent(stateIdentifier: String, timeout: Option[FiniteDuration]) extends PersistentFsmEvent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FSM state and data snapshot
|
||||||
|
*
|
||||||
|
* @param stateIdentifier FSM state identifier
|
||||||
|
* @param data FSM state data
|
||||||
|
* @param timeout FSM state timeout
|
||||||
|
* @tparam D state data type
|
||||||
|
*/
|
||||||
|
private[persistence] case class PersistentFSMSnapshot[D](stateIdentifier: String, data: D, timeout: Option[FiniteDuration]) extends Message
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FSMState base trait, makes possible for simple default serialization by conversion to String
|
* FSMState base trait, makes possible for simple default serialization by conversion to String
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ package akka.persistence.serialization
|
||||||
import akka.actor.{ ActorPath, ExtendedActorSystem }
|
import akka.actor.{ ActorPath, ExtendedActorSystem }
|
||||||
import akka.persistence.AtLeastOnceDelivery._
|
import akka.persistence.AtLeastOnceDelivery._
|
||||||
import akka.persistence._
|
import akka.persistence._
|
||||||
import akka.persistence.fsm.PersistentFSM.StateChangeEvent
|
import akka.persistence.fsm.PersistentFSM.{ PersistentFSMSnapshot, StateChangeEvent }
|
||||||
import akka.persistence.serialization.{ MessageFormats ⇒ mf }
|
import akka.persistence.serialization.{ MessageFormats ⇒ mf }
|
||||||
import akka.serialization._
|
import akka.serialization._
|
||||||
import akka.protobuf._
|
import akka.protobuf._
|
||||||
|
|
@ -33,6 +33,7 @@ class MessageSerializer(val system: ExtendedActorSystem) extends BaseSerializer
|
||||||
val PersistentImplClass = classOf[PersistentImpl]
|
val PersistentImplClass = classOf[PersistentImpl]
|
||||||
val AtLeastOnceDeliverySnapshotClass = classOf[AtLeastOnceDeliverySnapshot]
|
val AtLeastOnceDeliverySnapshotClass = classOf[AtLeastOnceDeliverySnapshot]
|
||||||
val PersistentStateChangeEventClass = classOf[StateChangeEvent]
|
val PersistentStateChangeEventClass = classOf[StateChangeEvent]
|
||||||
|
val PersistentFSMSnapshotClass = classOf[PersistentFSMSnapshot[Any]]
|
||||||
|
|
||||||
private lazy val serialization = SerializationExtension(system)
|
private lazy val serialization = SerializationExtension(system)
|
||||||
|
|
||||||
|
|
@ -53,6 +54,7 @@ class MessageSerializer(val system: ExtendedActorSystem) extends BaseSerializer
|
||||||
case a: AtomicWrite ⇒ atomicWriteBuilder(a).build().toByteArray
|
case a: AtomicWrite ⇒ atomicWriteBuilder(a).build().toByteArray
|
||||||
case a: AtLeastOnceDeliverySnapshot ⇒ atLeastOnceDeliverySnapshotBuilder(a).build.toByteArray
|
case a: AtLeastOnceDeliverySnapshot ⇒ atLeastOnceDeliverySnapshotBuilder(a).build.toByteArray
|
||||||
case s: StateChangeEvent ⇒ stateChangeBuilder(s).build.toByteArray
|
case s: StateChangeEvent ⇒ stateChangeBuilder(s).build.toByteArray
|
||||||
|
case p: PersistentFSMSnapshot[Any] ⇒ persistentFSMSnapshotBuilder(p).build.toByteArray
|
||||||
case _ ⇒ throw new IllegalArgumentException(s"Can't serialize object of type ${o.getClass}")
|
case _ ⇒ throw new IllegalArgumentException(s"Can't serialize object of type ${o.getClass}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,6 +70,7 @@ class MessageSerializer(val system: ExtendedActorSystem) extends BaseSerializer
|
||||||
case AtomicWriteClass ⇒ atomicWrite(mf.AtomicWrite.parseFrom(bytes))
|
case AtomicWriteClass ⇒ atomicWrite(mf.AtomicWrite.parseFrom(bytes))
|
||||||
case AtLeastOnceDeliverySnapshotClass ⇒ atLeastOnceDeliverySnapshot(mf.AtLeastOnceDeliverySnapshot.parseFrom(bytes))
|
case AtLeastOnceDeliverySnapshotClass ⇒ atLeastOnceDeliverySnapshot(mf.AtLeastOnceDeliverySnapshot.parseFrom(bytes))
|
||||||
case PersistentStateChangeEventClass ⇒ stateChange(mf.PersistentStateChangeEvent.parseFrom(bytes))
|
case PersistentStateChangeEventClass ⇒ stateChange(mf.PersistentStateChangeEvent.parseFrom(bytes))
|
||||||
|
case PersistentFSMSnapshotClass ⇒ persistentFSMSnapshot(mf.PersistentFSMSnapshot.parseFrom(bytes))
|
||||||
case _ ⇒ throw new IllegalArgumentException(s"Can't deserialize object of type ${c}")
|
case _ ⇒ throw new IllegalArgumentException(s"Can't deserialize object of type ${c}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +97,17 @@ class MessageSerializer(val system: ExtendedActorSystem) extends BaseSerializer
|
||||||
val builder = mf.PersistentStateChangeEvent.newBuilder.setStateIdentifier(stateChange.stateIdentifier)
|
val builder = mf.PersistentStateChangeEvent.newBuilder.setStateIdentifier(stateChange.stateIdentifier)
|
||||||
stateChange.timeout match {
|
stateChange.timeout match {
|
||||||
case None ⇒ builder
|
case None ⇒ builder
|
||||||
case Some(timeout) ⇒ builder.setTimeout(timeout.toString())
|
case Some(timeout) ⇒ builder.setTimeoutNanos(timeout.toNanos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private[persistence] def persistentFSMSnapshotBuilder(persistentFSMSnapshot: PersistentFSMSnapshot[Any]): mf.PersistentFSMSnapshot.Builder = {
|
||||||
|
val builder = mf.PersistentFSMSnapshot.newBuilder
|
||||||
|
.setStateIdentifier(persistentFSMSnapshot.stateIdentifier)
|
||||||
|
.setData(persistentPayloadBuilder(persistentFSMSnapshot.data.asInstanceOf[AnyRef]))
|
||||||
|
persistentFSMSnapshot.timeout match {
|
||||||
|
case None ⇒ builder
|
||||||
|
case Some(timeout) ⇒ builder.setTimeoutNanos(timeout.toNanos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,7 +127,17 @@ class MessageSerializer(val system: ExtendedActorSystem) extends BaseSerializer
|
||||||
def stateChange(persistentStateChange: mf.PersistentStateChangeEvent): StateChangeEvent = {
|
def stateChange(persistentStateChange: mf.PersistentStateChangeEvent): StateChangeEvent = {
|
||||||
StateChangeEvent(
|
StateChangeEvent(
|
||||||
persistentStateChange.getStateIdentifier,
|
persistentStateChange.getStateIdentifier,
|
||||||
if (persistentStateChange.hasTimeout) Some(Duration(persistentStateChange.getTimeout).asInstanceOf[duration.FiniteDuration]) else None)
|
// timeout field is deprecated, left for backward compatibility. timeoutNanos is used instead.
|
||||||
|
if (persistentStateChange.hasTimeoutNanos) Some(Duration.fromNanos(persistentStateChange.getTimeoutNanos))
|
||||||
|
else if (persistentStateChange.hasTimeout) Some(Duration(persistentStateChange.getTimeout).asInstanceOf[duration.FiniteDuration])
|
||||||
|
else None)
|
||||||
|
}
|
||||||
|
|
||||||
|
def persistentFSMSnapshot(persistentFSMSnapshot: mf.PersistentFSMSnapshot): PersistentFSMSnapshot[Any] = {
|
||||||
|
PersistentFSMSnapshot(
|
||||||
|
persistentFSMSnapshot.getStateIdentifier,
|
||||||
|
payload(persistentFSMSnapshot.getData),
|
||||||
|
if (persistentFSMSnapshot.hasTimeoutNanos) Some(Duration.fromNanos(persistentFSMSnapshot.getTimeoutNanos)) else None)
|
||||||
}
|
}
|
||||||
|
|
||||||
private def atomicWriteBuilder(a: AtomicWrite) = {
|
private def atomicWriteBuilder(a: AtomicWrite) = {
|
||||||
|
|
|
||||||
|
|
@ -532,17 +532,25 @@ public class AbstractPersistentFSMTest extends JUnitSuite {
|
||||||
stay().applying(new ItemAdded(event.getItem()))
|
stay().applying(new ItemAdded(event.getItem()))
|
||||||
.forMax(Duration.create(1, TimeUnit.SECONDS)))
|
.forMax(Duration.create(1, TimeUnit.SECONDS)))
|
||||||
.event(Buy.class,
|
.event(Buy.class,
|
||||||
|
//#customer-andthen-example
|
||||||
(event, data) ->
|
(event, data) ->
|
||||||
goTo(UserState.PAID).applying(OrderExecuted.INSTANCE)
|
goTo(UserState.PAID).applying(OrderExecuted.INSTANCE)
|
||||||
.andThen(exec(cart ->
|
.andThen(exec(cart -> {
|
||||||
reportActor.tell(new PurchaseWasMade(cart.getItems()), self()))
|
reportActor.tell(new PurchaseWasMade(cart.getItems()), self());
|
||||||
))
|
//#customer-andthen-example
|
||||||
|
saveStateSnapshot();
|
||||||
|
//#customer-andthen-example
|
||||||
|
})))
|
||||||
|
//#customer-andthen-example
|
||||||
.event(Leave.class,
|
.event(Leave.class,
|
||||||
|
//#customer-snapshot-example
|
||||||
(event, data) ->
|
(event, data) ->
|
||||||
stop().applying(OrderDiscarded.INSTANCE)
|
stop().applying(OrderDiscarded.INSTANCE)
|
||||||
.andThen(exec(cart ->
|
.andThen(exec(cart -> {
|
||||||
reportActor.tell(ShoppingCardDiscarded.INSTANCE, self())
|
reportActor.tell(ShoppingCardDiscarded.INSTANCE, self());
|
||||||
)))
|
saveStateSnapshot();
|
||||||
|
})))
|
||||||
|
//#customer-snapshot-example
|
||||||
.event(GetCurrentCart.class, (event, data) -> stay().replying(data))
|
.event(GetCurrentCart.class, (event, data) -> stay().replying(data))
|
||||||
.event(StateTimeout$.class,
|
.event(StateTimeout$.class,
|
||||||
(event, data) ->
|
(event, data) ->
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
package akka.persistence.fsm
|
package akka.persistence.fsm
|
||||||
|
|
||||||
import akka.actor._
|
import akka.actor._
|
||||||
import akka.persistence.{ PersistentActor, RecoveryCompleted, PersistenceSpec }
|
import akka.persistence._
|
||||||
import akka.persistence.fsm.PersistentFSM._
|
import akka.persistence.fsm.PersistentFSM._
|
||||||
import akka.testkit._
|
import akka.testkit._
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
|
|
@ -248,9 +248,6 @@ abstract class PersistentFSMSpec(config: Config) extends PersistenceSpec(config)
|
||||||
fsmRef ! GetCurrentCart
|
fsmRef ! GetCurrentCart
|
||||||
fsmRef ! AddItem(coat)
|
fsmRef ! AddItem(coat)
|
||||||
fsmRef ! GetCurrentCart
|
fsmRef ! GetCurrentCart
|
||||||
fsmRef ! Buy
|
|
||||||
fsmRef ! GetCurrentCart
|
|
||||||
fsmRef ! Leave
|
|
||||||
|
|
||||||
expectMsg(EmptyShoppingCart)
|
expectMsg(EmptyShoppingCart)
|
||||||
|
|
||||||
|
|
@ -258,8 +255,7 @@ abstract class PersistentFSMSpec(config: Config) extends PersistenceSpec(config)
|
||||||
expectMsg(NonEmptyShoppingCart(List(shirt, shoes)))
|
expectMsg(NonEmptyShoppingCart(List(shirt, shoes)))
|
||||||
expectMsg(NonEmptyShoppingCart(List(shirt, shoes, coat)))
|
expectMsg(NonEmptyShoppingCart(List(shirt, shoes, coat)))
|
||||||
|
|
||||||
expectMsg(NonEmptyShoppingCart(List(shirt, shoes, coat)))
|
fsmRef ! PoisonPill
|
||||||
|
|
||||||
expectTerminated(fsmRef)
|
expectTerminated(fsmRef)
|
||||||
|
|
||||||
val persistentEventsStreamer = system.actorOf(PersistentEventsStreamer.props(persistenceId, testActor))
|
val persistentEventsStreamer = system.actorOf(PersistentEventsStreamer.props(persistenceId, testActor))
|
||||||
|
|
@ -273,15 +269,67 @@ abstract class PersistentFSMSpec(config: Config) extends PersistenceSpec(config)
|
||||||
expectMsg(ItemAdded(Item("3", "Coat", 119.99F)))
|
expectMsg(ItemAdded(Item("3", "Coat", 119.99F)))
|
||||||
expectMsgType[StateChangeEvent] //because a timeout is defined, State Change is persisted
|
expectMsgType[StateChangeEvent] //because a timeout is defined, State Change is persisted
|
||||||
|
|
||||||
expectMsg(OrderExecuted)
|
watch(persistentEventsStreamer)
|
||||||
expectMsgType[StateChangeEvent]
|
persistentEventsStreamer ! PoisonPill
|
||||||
|
expectTerminated(persistentEventsStreamer)
|
||||||
|
}
|
||||||
|
|
||||||
|
"persist snapshot" in {
|
||||||
|
val persistenceId = name
|
||||||
|
|
||||||
|
val fsmRef = system.actorOf(WebStoreCustomerFSM.props(persistenceId, dummyReportActorRef))
|
||||||
|
watch(fsmRef)
|
||||||
|
|
||||||
|
val shirt = Item("1", "Shirt", 59.99F)
|
||||||
|
val shoes = Item("2", "Shoes", 89.99F)
|
||||||
|
val coat = Item("3", "Coat", 119.99F)
|
||||||
|
|
||||||
|
fsmRef ! GetCurrentCart
|
||||||
|
fsmRef ! AddItem(shirt)
|
||||||
|
fsmRef ! GetCurrentCart
|
||||||
|
fsmRef ! AddItem(shoes)
|
||||||
|
fsmRef ! GetCurrentCart
|
||||||
|
fsmRef ! AddItem(coat)
|
||||||
|
fsmRef ! GetCurrentCart
|
||||||
|
fsmRef ! Buy
|
||||||
|
fsmRef ! GetCurrentCart
|
||||||
|
|
||||||
|
expectMsg(EmptyShoppingCart)
|
||||||
|
|
||||||
|
expectMsg(NonEmptyShoppingCart(List(shirt)))
|
||||||
|
expectMsg(NonEmptyShoppingCart(List(shirt, shoes)))
|
||||||
|
expectMsg(NonEmptyShoppingCart(List(shirt, shoes, coat)))
|
||||||
|
|
||||||
|
expectMsg(NonEmptyShoppingCart(List(shirt, shoes, coat)))
|
||||||
|
expectNoMsg(1 second)
|
||||||
|
|
||||||
|
fsmRef ! PoisonPill
|
||||||
|
expectTerminated(fsmRef)
|
||||||
|
|
||||||
|
//Check that PersistentFSM recovers in the correct state
|
||||||
|
val recoveredFsmRef = system.actorOf(WebStoreCustomerFSM.props(persistenceId, dummyReportActorRef))
|
||||||
|
recoveredFsmRef ! GetCurrentCart
|
||||||
|
expectMsg(NonEmptyShoppingCart(List(shirt, shoes, coat)))
|
||||||
|
|
||||||
|
watch(recoveredFsmRef)
|
||||||
|
recoveredFsmRef ! PoisonPill
|
||||||
|
expectTerminated(recoveredFsmRef)
|
||||||
|
|
||||||
|
//Check that PersistentFSM uses snapshot during recovery
|
||||||
|
val persistentEventsStreamer = system.actorOf(PersistentEventsStreamer.props(persistenceId, testActor))
|
||||||
|
|
||||||
|
expectMsgPF() {
|
||||||
|
case SnapshotOffer(SnapshotMetadata(name, _, timestamp), PersistentFSMSnapshot(stateIdentifier, cart, None)) ⇒
|
||||||
|
stateIdentifier should ===(Paid.identifier)
|
||||||
|
cart should ===(NonEmptyShoppingCart(List(shirt, shoes, coat)))
|
||||||
|
timestamp should be > 0L
|
||||||
|
}
|
||||||
|
|
||||||
watch(persistentEventsStreamer)
|
watch(persistentEventsStreamer)
|
||||||
persistentEventsStreamer ! PoisonPill
|
persistentEventsStreamer ! PoisonPill
|
||||||
expectTerminated(persistentEventsStreamer)
|
expectTerminated(persistentEventsStreamer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object PersistentFSMSpec {
|
object PersistentFSMSpec {
|
||||||
|
|
@ -379,14 +427,24 @@ object PersistentFSMSpec {
|
||||||
case Event(AddItem(item), _) ⇒
|
case Event(AddItem(item), _) ⇒
|
||||||
stay applying ItemAdded(item) forMax (1 seconds)
|
stay applying ItemAdded(item) forMax (1 seconds)
|
||||||
case Event(Buy, _) ⇒
|
case Event(Buy, _) ⇒
|
||||||
|
//#customer-andthen-example
|
||||||
goto(Paid) applying OrderExecuted andThen {
|
goto(Paid) applying OrderExecuted andThen {
|
||||||
case NonEmptyShoppingCart(items) ⇒ reportActor ! PurchaseWasMade(items)
|
case NonEmptyShoppingCart(items) ⇒
|
||||||
case EmptyShoppingCart ⇒ // do nothing...
|
reportActor ! PurchaseWasMade(items)
|
||||||
|
//#customer-andthen-example
|
||||||
|
saveStateSnapshot()
|
||||||
|
case EmptyShoppingCart ⇒ saveStateSnapshot()
|
||||||
|
//#customer-andthen-example
|
||||||
}
|
}
|
||||||
|
//#customer-andthen-example
|
||||||
case Event(Leave, _) ⇒
|
case Event(Leave, _) ⇒
|
||||||
|
//#customer-snapshot-example
|
||||||
stop applying OrderDiscarded andThen {
|
stop applying OrderDiscarded andThen {
|
||||||
case _ ⇒ reportActor ! ShoppingCardDiscarded
|
case _ ⇒
|
||||||
|
reportActor ! ShoppingCardDiscarded
|
||||||
|
saveStateSnapshot()
|
||||||
}
|
}
|
||||||
|
//#customer-snapshot-example
|
||||||
case Event(GetCurrentCart, data) ⇒
|
case Event(GetCurrentCart, data) ⇒
|
||||||
stay replying data
|
stay replying data
|
||||||
case Event(StateTimeout, _) ⇒
|
case Event(StateTimeout, _) ⇒
|
||||||
|
|
|
||||||
|
|
@ -780,7 +780,14 @@ object MiMa extends AutoPlugin {
|
||||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("akka.http.impl.engine.parsing.HttpMessageParser.stage"),
|
ProblemFilters.exclude[IncompatibleResultTypeProblem]("akka.http.impl.engine.parsing.HttpMessageParser.stage"),
|
||||||
|
|
||||||
// #20131 - flow combinator
|
// #20131 - flow combinator
|
||||||
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.stream.scaladsl.FlowOps.backpressureTimeout")
|
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.stream.scaladsl.FlowOps.backpressureTimeout"),
|
||||||
|
|
||||||
|
// #20257 Snapshots with PersistentFSM (experimental feature)
|
||||||
|
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.persistence.serialization.MessageFormats#PersistentStateChangeEventOrBuilder.getTimeoutNanos"),
|
||||||
|
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.persistence.serialization.MessageFormats#PersistentStateChangeEventOrBuilder.hasTimeoutNanos"),
|
||||||
|
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.persistence.fsm.PersistentFSM.saveStateSnapshot"),
|
||||||
|
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.persistence.fsm.PersistentFSM.akka$persistence$fsm$PersistentFSM$$currentStateTimeout"),
|
||||||
|
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.persistence.fsm.PersistentFSM.akka$persistence$fsm$PersistentFSM$$currentStateTimeout_=")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue