The RecoveringClientActorBehavior increments the last generation id and
saves a new snapshot. However the prior snapshots remain in akka
persistence - every time the controller is restarted a new snapshot file
is created. We should delete the prior snaphsots.
The snapshot file names were very long with escape chars b/c
FrontendIdentifier.toString is used for the frontend client actor's
persistence ID. We should use a shorter, more readable ID, so I changed
it to the form:
member-1-frontend-datastore-config
member-1-frontend-datastore-operational
Change-Id: I1c77c826729ca1a36497a1236ac99f7cc77efb72
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
package org.opendaylight.controller.cluster.access.concepts;
import com.google.common.annotations.Beta;
package org.opendaylight.controller.cluster.access.concepts;
import com.google.common.annotations.Beta;
-import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import java.io.DataInput;
import java.io.DataOutput;
import com.google.common.base.Preconditions;
import java.io.DataInput;
import java.io.DataOutput;
return memberName.equals(other.memberName) && clientType.equals(other.clientType);
}
return memberName.equals(other.memberName) && clientType.equals(other.clientType);
}
+ public String toPersistentId() {
+ return memberName.getName() + "-frontend-" + clientType.getName();
+ }
+
@Override
public String toString() {
@Override
public String toString() {
- return MoreObjects.toStringHelper(FrontendIdentifier.class).add("member", memberName)
- .add("clientType", clientType).toString();
+ return toPersistentId();
}
private Object writeReplace() {
}
private Object writeReplace() {
}
public static Props props(final @Nonnull MemberName memberName, @Nonnull final String storeName, final ActorContext ctx) {
}
public static Props props(final @Nonnull MemberName memberName, @Nonnull final String storeName, final ActorContext ctx) {
- final String name = "DistributedDataStore:storeName='" + storeName + "'";
+ final String name = "datastore-" + storeName;
final FrontendIdentifier frontendId = FrontendIdentifier.create(memberName, FrontendType.forName(name));
return Props.create(DistributedDataStoreClientActor.class,
() -> new DistributedDataStoreClientActor(frontendId, ctx));
final FrontendIdentifier frontendId = FrontendIdentifier.create(memberName, FrontendType.forName(name));
return Props.create(DistributedDataStoreClientActor.class,
() -> new DistributedDataStoreClientActor(frontendId, ctx));
protected AbstractClientActor(final FrontendIdentifier frontendId) {
currentBehavior = new RecoveringClientActorBehavior(
protected AbstractClientActor(final FrontendIdentifier frontendId) {
currentBehavior = new RecoveringClientActorBehavior(
- new InitialClientActorContext(this, frontendId.toString()), frontendId);
+ new InitialClientActorContext(this, frontendId.toPersistentId()), frontendId);
package org.opendaylight.controller.cluster.datastore.actors.client;
import akka.actor.ActorSystem;
package org.opendaylight.controller.cluster.datastore.actors.client;
import akka.actor.ActorSystem;
+import akka.persistence.SnapshotSelectionCriteria;
import com.google.common.base.Preconditions;
import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
import com.google.common.base.Preconditions;
import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
actor.saveSnapshot(snapshot);
}
actor.saveSnapshot(snapshot);
}
+ void deleteSnapshots(SnapshotSelectionCriteria criteria) {
+ actor.deleteSnapshots(criteria);
+ }
+
ClientActorBehavior createBehavior(final ClientIdentifier clientId) {
final ActorSystem system = actor.getContext().system();
final ClientActorContext context = new ClientActorContext(self(), system.scheduler(), system.dispatcher(),
ClientActorBehavior createBehavior(final ClientIdentifier clientId) {
final ActorSystem system = actor.getContext().system();
final ClientActorContext context = new ClientActorContext(self(), system.scheduler(), system.dispatcher(),
import akka.persistence.SaveSnapshotFailure;
import akka.persistence.SaveSnapshotSuccess;
import akka.persistence.SaveSnapshotFailure;
import akka.persistence.SaveSnapshotSuccess;
+import akka.persistence.SnapshotSelectionCriteria;
import com.google.common.base.Preconditions;
import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
import org.slf4j.Logger;
import com.google.common.base.Preconditions;
import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
import org.slf4j.Logger;
return null;
} else if (command instanceof SaveSnapshotSuccess) {
context().unstash();
return null;
} else if (command instanceof SaveSnapshotSuccess) {
context().unstash();
+
+ SaveSnapshotSuccess saved = (SaveSnapshotSuccess)command;
+ context().deleteSnapshots(new SnapshotSelectionCriteria(saved.metadata().sequenceNr(),
+ saved.metadata().timestamp() - 1, 0L, 0L));
+
return context().createBehavior(myId);
} else {
LOG.debug("{}: stashing command {}", persistenceId(), command);
return context().createBehavior(myId);
} else {
LOG.debug("{}: stashing command {}", persistenceId(), command);
Object id = transactionProxy.getIdentifier();
assertNotNull("getIdentifier returned null", id);
Object id = transactionProxy.getIdentifier();
assertNotNull("getIdentifier returned null", id);
- assertTrue("Invalid identifier: " + id, id.toString().contains(MemberName.forName(memberName).toString()));
+ assertTrue("Invalid identifier: " + id, id.toString().contains(memberName));