Package ratpack.exec

Interface ExecInterceptor

  • All Known Subinterfaces:
    BlockingExecTimingInterceptor
    All Known Implementing Classes:
    MDCInterceptor
    Functional Interface:
    This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

    @FunctionalInterface
    public interface ExecInterceptor
    Intercepts execution segments of an execution, primarily for traceability and recording metrics.

    Interceptors present in the base registry will be implicitly applied to all executions. Execution specific interceptors can be registered via the ExecStarter.register(Action) method when starting the execution. The Execution.addInterceptor(ExecInterceptor, Block) method allows interceptors to be registered during an execution, for the rest of the execution.

    
     import ratpack.exec.ExecInterceptor;
     import ratpack.exec.Execution;
     import ratpack.exec.Blocking;
     import ratpack.exec.ExecResult;
     import ratpack.func.Block;
     import ratpack.test.exec.ExecHarness;
    
     import static java.lang.Thread.sleep;
     import static org.junit.jupiter.api.Assertions.assertEquals;
     import static org.junit.jupiter.api.Assertions.assertTrue;
    
     public class Example {
    
       public static class Timer {
         private long totalCompute;
         private long totalBlocking;
         private boolean blocking;
    
         private long startedAt;
    
         public void start(boolean blocking) {
           this.blocking = blocking;
           startedAt = System.currentTimeMillis();
         }
    
         public void stop() {
           long duration = System.currentTimeMillis() - startedAt;
           if (blocking) {
             totalBlocking += duration;
           } else {
             totalCompute += duration;
           }
         }
    
         public long getBlockingTime() {
           return totalBlocking;
         }
    
         public long getComputeTime() {
           return totalCompute;
         }
       }
    
       public static class ProcessingTimingInterceptor implements ExecInterceptor {
         public void intercept(Execution execution, ExecInterceptor.ExecType type, Block continuation) throws Exception {
           Timer timer = execution.maybeGet(Timer.class).orElse(null);
           if (timer == null) { // this is the first execution segment
             timer = new Timer();
             execution.add(Timer.class, timer);
           }
    
           timer.start(type.equals(ExecInterceptor.ExecType.BLOCKING));
           try {
             continuation.execute();
           } finally {
             timer.stop();
           }
         }
       }
    
       public static void main(String[] args) throws Exception {
         ExecResult<Timer> result = ExecHarness.yieldSingle(
           r -> r.add(new ProcessingTimingInterceptor()), // add the interceptor to the registry
           e -> {
             Thread.sleep(100);
             return Blocking.get(() -> {
               Thread.sleep(100);
               return Execution.current().get(Timer.class);
             })
             .map(s -> {
               Thread.sleep(100);
               return s;
             });
           }
         );
    
         Timer timer = result.getValue();
         assertTrue(timer.getBlockingTime() >= 100);
         assertTrue(timer.getComputeTime() >= 200);
       }
     }
     
    See Also:
    Execution.addInterceptor(ExecInterceptor, Block)
    • Method Detail

      • intercept

        void intercept​(Execution execution,
                       ExecInterceptor.ExecType execType,
                       Block executionSegment)
                throws Exception
        Intercepts the execution of an execution segment.

        The execution segment argument represents a unit of work of the execution.

        Implementations MUST invoke execute() on the given execution segment block.

        Parameters:
        execution - the execution that this segment belongs to
        execType - indicates whether this segment is execution on a compute or blocking thread
        executionSegment - the execution segment that is to be executed
        Throws:
        Exception - any