All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.infinispan.interceptors.BaseAsyncInterceptor Maven / Gradle / Ivy

There is a newer version: 9.1.7.Final
Show newest version
package org.infinispan.interceptors;

import java.util.concurrent.CompletableFuture;

import org.infinispan.commands.VisitableCommand;
import org.infinispan.commons.util.Experimental;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.context.InvocationContext;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.interceptors.impl.BasicAsyncInvocationStage;
import org.infinispan.interceptors.impl.AsyncInvocationStage;
import org.infinispan.interceptors.impl.ExceptionStage;
import org.infinispan.interceptors.impl.ReturnValueStage;
import org.infinispan.util.concurrent.CompletableFutures;

/**
 * Base class for an interceptor in the new asynchronous invocation chain.
 *
 * @author Dan Berindei
 * @since 9.0
 */
@Experimental
public abstract class BaseAsyncInterceptor implements AsyncInterceptor {
   protected Configuration cacheConfiguration;
   private AsyncInterceptor nextInterceptor;

   @Inject
   public void inject(Configuration cacheConfiguration) {
      this.cacheConfiguration = cacheConfiguration;
   }

   /**
    * Used internally to set up the interceptor.
    */
   @Override
   public final void setNextInterceptor(AsyncInterceptor nextInterceptor) {
      this.nextInterceptor = nextInterceptor;
   }

   /**
    * Invoke the next interceptor, possibly with a new command.
    *
    * 

{@link InvocationStage} then allows the caller to add a callback that will be executed after the remaining * interceptors.

*

Note: {@code invokeNext(ctx, command)} does not throw exceptions. In order to handle exceptions from the * next interceptors, you must use {@link InvocationStage#exceptionally(InvocationExceptionHandler)}, * {@link InvocationStage#handle(InvocationFinallyHandler)}, or {@link InvocationStage#compose(InvocationComposeHandler)}

*/ public InvocationStage invokeNext(InvocationContext ctx, VisitableCommand command) { try { BasicInvocationStage stage = nextInterceptor.visitCommand(ctx, command); return stage.toInvocationStage(ctx, command); } catch (Throwable throwable) { return new ExceptionStage(ctx, command, throwable); } } /** * Return a value directly, skipping the remaining interceptors in the chain. */ public BasicInvocationStage returnWith(Object returnValue) { return new ReturnValueStage(null, null, returnValue); } /** * Suspend the invocation until {@code stageFuture} completes, then evaluate its result and skip the remaining * interceptors. *

* The caller is supposed to call the */ public InvocationStage goAsync(InvocationContext ctx, VisitableCommand command, CompletableFuture valueFuture) { if (valueFuture.isDone()) { InvocationStage stage; try { Object value = valueFuture.join(); stage = new ReturnValueStage(ctx, command, value); } catch (Throwable t) { stage = new ExceptionStage(ctx, command, CompletableFutures.extractException(t)); } return stage; } return new AsyncInvocationStage(ctx, command, valueFuture); } /** * Suspend the invocation until {@code delay} completes, then if successful invoke the next interceptor. *

* If {@code delay} completes exceptionally, skip the next interceptor and continue with the exception. */ public InvocationStage invokeNextAsync(InvocationContext ctx, VisitableCommand command, CompletableFuture delay) { if (delay.isDone()) { InvocationStage stage; try { // Make sure the delay was successful delay.join(); stage = invokeNext(ctx, command); } catch (Throwable t) { stage = new ExceptionStage(ctx, command, CompletableFutures.extractException(t)); } return stage; } return new AsyncInvocationStage(ctx, command, delay).thenCompose( (stage, rCtx, rCommand, rv) -> invokeNext(rCtx, rCommand)); } /** * Suspend the invocation until {@code returnValueFuture} completes, then return its result and skip the remaining * interceptors. *

* The caller can continue invoking the next interceptor, e.g. * {@code goAsync2(ctx, command, v).thenApply((rCtx, rCommand, rv, t) -> invokeNext(rCtx, rCommand))} */ public BasicInvocationStage returnWithAsync(CompletableFuture valueFuture) { if (valueFuture.isDone()) { InvocationStage stage; try { Object value = valueFuture.join(); stage = new ReturnValueStage(null, null, value); } catch (Throwable t) { stage = new ExceptionStage(null, null, CompletableFutures.extractException(t)); } return stage; } return new BasicAsyncInvocationStage(valueFuture); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy