BUG-5280: add AbstractClientConnection
[controller.git] / opendaylight / md-sal / cds-access-client / src / main / java / org / opendaylight / controller / cluster / access / client / BackendInfoResolver.java
index 71805735f0587e7663ab9dbdbca5226e4a1089ce..e4aa2b1e75e267e1f6b4599c1e5c6347153e3c81 100644 (file)
@@ -8,18 +8,8 @@
 package org.opendaylight.controller.cluster.access.client;
 
 import akka.actor.ActorRef;
-import com.google.common.base.Preconditions;
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
 import javax.annotation.Nonnull;
-import javax.annotation.concurrent.ThreadSafe;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Caching resolver which resolves a cookie to a leader {@link ActorRef}. This class needs to be specialized by the
@@ -29,70 +19,24 @@ import org.slf4j.LoggerFactory;
  *
  * @author Robert Varga
  */
-@ThreadSafe
 public abstract class BackendInfoResolver<T extends BackendInfo> {
-    private static final Logger LOG = LoggerFactory.getLogger(BackendInfoResolver.class);
-    private final ConcurrentMap<Long, CompletableFuture<T>> backends = new ConcurrentHashMap<>();
-
-    /**
-     * Return the currently-resolved backend information, if available. This method is guaranteed not to block, but will
-     * initiate resolution of the information if there is none.
-     *
-     * @param cookie Backend cookie
-     * @return Backend information, if available
-     */
-    public final Optional<T> getFutureBackendInfo(final Long cookie) {
-        final Future<T> f = lookupBackend(cookie);
-        if (f.isDone()) {
-            try {
-                return Optional.of(f.get());
-            } catch (InterruptedException | ExecutionException e) {
-                LOG.debug("Resolution of {} failed", f, e);
-            }
-        }
-
-        return Optional.empty();
-    }
-
     /**
-     * Invalidate a particular instance of {@link BackendInfo}, typically as a response to a request timing out. If
-     * the provided information is not the one currently cached this method does nothing.
+     * Request resolution of a particular backend identified by a cookie. This request can be satisfied from the cache.
      *
      * @param cookie Backend cookie
-     * @param info Previous information to be invalidated
+     * @return A {@link CompletionStage} resulting in information about the backend
      */
-    public final void invalidateBackend(final long cookie, @Nonnull final CompletionStage<? extends BackendInfo> info) {
-        if (backends.remove(cookie, Preconditions.checkNotNull(info))) {
-            LOG.trace("Invalidated cache %s -> %s", Long.toUnsignedString(cookie), info);
-            invalidateBackendInfo(info);
-        }
-    }
+    @Nonnull
+    public abstract CompletionStage<? extends T> getBackendInfo(@Nonnull Long cookie);
 
     /**
-     * Request new resolution of a particular backend identified by a cookie. This method is invoked when a client
-     * requests information which is not currently cached.
+     * Request re-resolution of a particular backend identified by a cookie, indicating a particular information as
+     * being stale. If the implementation's cache holds the stale information, it should be purged.
      *
      * @param cookie Backend cookie
-     * @return A {@link CompletableFuture} resulting in information about the backend
+     * @param staleInfo Stale backend information
+     * @return A {@link CompletionStage} resulting in information about the backend
      */
     @Nonnull
-    protected abstract CompletableFuture<T> resolveBackendInfo(@Nonnull final Long cookie);
-
-    /**
-     * Invalidate previously-resolved shard information. This method is invoked when a timeout is detected
-     * and the information may need to be refreshed.
-     *
-     * @param info Previous promise of backend information
-     */
-    protected abstract void invalidateBackendInfo(@Nonnull CompletionStage<? extends BackendInfo> info);
-
-    // This is what the client needs to start processing. For as long as we do not have this, we should not complete
-    // this stage until we have this information
-    final CompletionStage<? extends T> getBackendInfo(final Long cookie) {
-        return lookupBackend(cookie);
-    }
-
-    private CompletableFuture<T> lookupBackend(final Long cookie) {
-        return backends.computeIfAbsent(Preconditions.checkNotNull(cookie), this::resolveBackendInfo);
-    }
+    public abstract CompletionStage<? extends T> refreshBackendInfo(@Nonnull Long cookie, @Nonnull T staleInfo);
 }