BUG-5280: use a lambda for createLocalHistory()/close() 74/39574/38
authorRobert Varga <rovarga@cisco.com>
Sun, 29 May 2016 21:34:14 +0000 (23:34 +0200)
committerRobert Varga <rovarga@cisco.com>
Tue, 21 Jun 2016 08:54:31 +0000 (10:54 +0200)
These are internal commands, which can be efficiently implemented
using a simple delayed execution primitive.

Introduce ClientActorContext#executeInActor(), which will wrap
a specialized subclass of Runnable and send it to the actor.

This can be used to dispatch lambdas to methods, reducing the need
for specialized messages and instanceof checks.

Change-Id: Id5cd388657a274d551892a6c943b062d70c7bea7
Signed-off-by: Robert Varga <rovarga@cisco.com>
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/CreateLocalHistoryCommand.java [deleted file]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/DistributedDataStoreClientBehavior.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/actors/client/ClientActorBehavior.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/actors/client/ClientActorContext.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/actors/client/InternalCommand.java [new file with mode: 0644]

diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/CreateLocalHistoryCommand.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/CreateLocalHistoryCommand.java
deleted file mode 100644 (file)
index 197b2f6..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.cluster.databroker.actors.dds;
-
-import java.util.concurrent.CompletableFuture;
-
-/**
- * Command sent from the Java world to the client actor to create a new local history.
- *
- * @author Robert Varga
- */
-final class CreateLocalHistoryCommand {
-    private final CompletableFuture<ClientLocalHistory> future = new CompletableFuture<>();
-
-    CompletableFuture<ClientLocalHistory> future() {
-        return future;
-    }
-}
index 917e759..cacda93 100644 (file)
@@ -45,12 +45,6 @@ import org.slf4j.LoggerFactory;
  */
 final class DistributedDataStoreClientBehavior extends ClientActorBehavior implements DistributedDataStoreClient {
     private static final Logger LOG = LoggerFactory.getLogger(DistributedDataStoreClientBehavior.class);
-    private static final Object SHUTDOWN = new Object() {
-        @Override
-        public String toString() {
-            return "SHUTDOWN";
-        }
-    };
 
     private long nextHistoryId;
 
@@ -69,24 +63,24 @@ final class DistributedDataStoreClientBehavior extends ClientActorBehavior imple
         // FIXME: Add state flushing here once we have state
     }
 
-    private void createLocalHistory(final CreateLocalHistoryCommand command) {
-        final CompletableFuture<ClientLocalHistory> future = command.future();
+    private ClientActorBehavior createLocalHistory(final CompletableFuture<ClientLocalHistory> future) {
         final LocalHistoryIdentifier historyId = new LocalHistoryIdentifier(getIdentifier(), nextHistoryId++);
         LOG.debug("{}: creating a new local history {} for {}", persistenceId(), historyId, future);
 
         // FIXME: initiate backend instantiation
         future.completeExceptionally(new UnsupportedOperationException("Not implemented yet"));
+        return this;
+    }
+
+    private ClientActorBehavior shutdown() {
+        // FIXME: Add shutdown procedures here
+        return null;
     }
 
     @Override
     protected ClientActorBehavior onCommand(final Object command) {
-        if (command instanceof CreateLocalHistoryCommand) {
-            createLocalHistory((CreateLocalHistoryCommand) command);
-        } else if (command instanceof GetClientRequest) {
+        if (command instanceof GetClientRequest) {
             ((GetClientRequest) command).getReplyTo().tell(new Status.Success(this), ActorRef.noSender());
-        } else if (SHUTDOWN.equals(command)) {
-            // FIXME: Add shutdown procedures here
-            return null;
         } else {
             LOG.warn("{}: ignoring unhandled command {}", persistenceId(), command);
         }
@@ -102,13 +96,13 @@ final class DistributedDataStoreClientBehavior extends ClientActorBehavior imple
 
     @Override
     public CompletionStage<ClientLocalHistory> createLocalHistory() {
-        final CreateLocalHistoryCommand command = new CreateLocalHistoryCommand();
-        self().tell(command, ActorRef.noSender());
-        return command.future();
+        final CompletableFuture<ClientLocalHistory> future = new CompletableFuture<>();
+        context().executeInActor(() -> createLocalHistory(future));
+        return future;
     }
 
     @Override
     public void close() {
-        self().tell(SHUTDOWN, ActorRef.noSender());
+        context().executeInActor(this::shutdown);
     }
 }
index 1d812b7..7ac06d3 100644 (file)
@@ -36,7 +36,9 @@ public abstract class ClientActorBehavior extends RecoveredClientActorBehavior<C
 
     @Override
     final ClientActorBehavior onReceiveCommand(final Object command) {
-        if (command instanceof RequestFailure) {
+        if (command instanceof InternalCommand) {
+            return ((InternalCommand) command).execute();
+        } else if (command instanceof RequestFailure) {
             final RequestFailure<?, ?> failure = (RequestFailure<?, ?>) command;
             final RequestException cause = failure.getCause();
             if (cause instanceof RetiredGenerationException) {
index 9fc17b5..3aa1a52 100644 (file)
@@ -49,4 +49,13 @@ public class ClientActorContext extends AbstractClientActorContext implements Id
     public @Nonnull Ticker ticker() {
         return Ticker.systemTicker();
     }
+
+    /**
+     * Execute a command in the context of the client actor.
+     *
+     * @param command Block of code which needs to be execute
+     */
+    public void executeInActor(final @Nonnull InternalCommand command) {
+        self().tell(Preconditions.checkNotNull(command), ActorRef.noSender());
+    }
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/actors/client/InternalCommand.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/actors/client/InternalCommand.java
new file mode 100644 (file)
index 0000000..c72b854
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.datastore.actors.client;
+
+import javax.annotation.Nullable;
+
+/**
+ * This interface is used to pass the unit of work via the actors mailbox. The command can alter behavior of the actor
+ * by returning a new behavior.
+ *
+ * @author Robert Varga
+ */
+@FunctionalInterface
+public interface InternalCommand {
+    /**
+     * Run command actions.
+     *
+     * @return Next behavior to use in the client actor
+     */
+    @Nullable ClientActorBehavior execute();
+}