The interception methods wrap the rest of the execution. They receive a continuation (as a {@link Runnable}) that must be called in order for processing to proceed.
Request handling execution can be intercepted by the {@link ratpack.handling.Context#addInterceptor(ExecInterceptor,ratpack.func.Action)} method.
{@code import ratpack.exec.ExecInterceptor; import ratpack.http.Request; import ratpack.test.UnitTest; import ratpack.test.handling.HandlingResult; import java.util.concurrent.atomic.AtomicLong; import static java.lang.Thread.sleep;}public class Example public static class Timer { private final AtomicLong totalCompute = new AtomicLong(); private final AtomicLong totalBlocking = new AtomicLong(); private boolean blocking; private final ThreadLocalFor other types of executions (e.g. background jobs), the interceptor can be registered via {@link ratpack.exec.ExecControl#addInterceptor(ExecInterceptor,ratpack.func.Action)}. @see Execution @see ratpack.handling.Context#addInterceptor(ExecInterceptor,ratpack.func.Action)startedAt = ThreadLocal.withInitial(() -> 0l); public void start(boolean blocking) { this.blocking = blocking; startedAt.set(System.currentTimeMillis()); } public void stop() { long startedAtTime = startedAt.get(); startedAt.remove(); AtomicLong counter = blocking ? totalBlocking : totalCompute; counter.addAndGet(startedAtTime > 0 ? System.currentTimeMillis() - startedAtTime : 0); } public long getBlockingTime() { return totalBlocking.get(); } public long getComputeTime() { return totalCompute.get(); } } public static class ProcessingTimingInterceptor implements ExecInterceptor { private final Request request; public ProcessingTimingInterceptor(Request request) { this.request = request; request.add(new Timer()); } public void intercept(ExecInterceptor.ExecType type, Runnable continuation) { Timer timer = request.get(Timer.class); timer.start(type.equals(ExecInterceptor.ExecType.BLOCKING)); continuation.run(); timer.stop(); } } public static void main(String[] args) throws Exception { HandlingResult result = UnitTest.requestFixture().handleChain(chain -> chain .handler(context -> context.addInterceptor(new ProcessingTimingInterceptor(context.getRequest()), execution -> context.next()) ) .handler(context -> { sleep(100); context.blocking(() -> { sleep(100); return "foo"; }).then(string -> { sleep(100); context.render(string); }); }) ); assert result.rendered(String.class).equals("foo"); Timer timer = result.getRequestRegistry().get(Timer.class); assert timer.getBlockingTime() >= 100; assert timer.getComputeTime() >= 200; } } }
|
|