X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fcds-access-client%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Faccess%2Fclient%2FBackendInfoResolver.java;h=5c5cda5bae0b8f7eb2e4bb02bd827e47c234c07b;hp=cb648091203ba170014e084c30f01f93bf3f2b56;hb=HEAD;hpb=b0067e0a4bfa955f15c6259e019f954687264eff diff --git a/opendaylight/md-sal/cds-access-client/src/main/java/org/opendaylight/controller/cluster/access/client/BackendInfoResolver.java b/opendaylight/md-sal/cds-access-client/src/main/java/org/opendaylight/controller/cluster/access/client/BackendInfoResolver.java index cb64809120..5c5cda5bae 100644 --- a/opendaylight/md-sal/cds-access-client/src/main/java/org/opendaylight/controller/cluster/access/client/BackendInfoResolver.java +++ b/opendaylight/md-sal/cds-access-client/src/main/java/org/opendaylight/controller/cluster/access/client/BackendInfoResolver.java @@ -8,18 +8,10 @@ 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; +import java.util.function.Consumer; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.concepts.Registration; /** * Caching resolver which resolves a cookie to a leader {@link ActorRef}. This class needs to be specialized by the @@ -27,71 +19,47 @@ import org.slf4j.LoggerFactory; * by either the client actor (when a message timeout is detected) and by the specific frontend (on explicit * invalidation or when updated information becomes available). * + *

+ * If the completion stage returned by this interface's methods fails with a + * {@link org.opendaylight.controller.cluster.access.concepts.RequestException}, it will be forwarded to all + * outstanding requests towards the leader. If it fails with a {@link java.util.concurrent.TimeoutException}, + * resolution process will be retried. If it fails with any other cause, it will we wrapped as a + * {@link org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException} wrapping that cause. + * * @author Robert Varga */ -@ThreadSafe -public abstract class BackendInfoResolver { - private static final Logger LOG = LoggerFactory.getLogger(BackendInfoResolver.class); - private final ConcurrentMap> backends = new ConcurrentHashMap<>(); - +public abstract class BackendInfoResolver implements AutoCloseable { /** - * 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. + * Request resolution of a particular backend identified by a cookie. This request can be satisfied from the cache. * * @param cookie Backend cookie - * @return Backend information, if available + * @return A {@link CompletionStage} resulting in information about the backend */ - public final Optional getFutureBackendInfo(final Long cookie) { - final Future 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(); - } + public abstract @NonNull CompletionStage getBackendInfo(@NonNull Long cookie); /** - * 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 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 - * @param info Previous information to be invalidated + * @param staleInfo Stale backend information + * @return A {@link CompletionStage} resulting in information about the backend */ - public final void invalidateBackend(final long cookie, final @Nonnull CompletionStage info) { - if (backends.remove(cookie, Preconditions.checkNotNull(info))) { - LOG.trace("Invalidated cache %s -> %s", Long.toUnsignedString(cookie), info); - invalidateBackendInfo(info); - } - } + public abstract @NonNull CompletionStage refreshBackendInfo(@NonNull Long cookie, + @NonNull T staleInfo); /** - * 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. + * Registers a callback to be notified when BackendInfo that may have been previously obtained is now stale and + * should be refreshed. * - * @param cookie Backend cookie - * @return A {@link CompletableFuture} resulting in information about the backend + * @param callback the callback that takes the backend cookie whose BackendInfo is now stale. + * @return a Registration */ - protected abstract @Nonnull CompletableFuture resolveBackendInfo(final @Nonnull Long cookie); + public abstract @NonNull Registration notifyWhenBackendInfoIsStale(Consumer callback); - /** - * 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 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 getBackendInfo(final Long cookie) { - return lookupBackend(cookie); - } + public abstract @NonNull String resolveCookieName(Long cookie); - private CompletableFuture lookupBackend(final Long cookie) { - return backends.computeIfAbsent(Preconditions.checkNotNull(cookie), this::resolveBackendInfo); + @Override + public void close() { } }