public interface ExecInterceptor
The interception methods wrap the rest of the execution.
They receive a continuation (as a Runnable
) that must be called in order for processing to proceed.
Request handling execution can be intercepted by the Context.addInterceptor(ExecInterceptor, ratpack.func.Action)
method.
import ratpack.launch.LaunchConfig; import ratpack.launch.LaunchConfigBuilder; import ratpack.handling.Context; import ratpack.handling.Handler; import ratpack.handling.Chain; import ratpack.handling.ChainAction; import ratpack.http.Request; import ratpack.exec.Execution; import ratpack.exec.ExecInterceptor; import ratpack.func.Action; import ratpack.func.Actions; import ratpack.test.UnitTest; import ratpack.test.handling.HandlingResult; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicLong; public class Example { public static class Timer { private final AtomicLong totalCompute = new AtomicLong(); private final AtomicLong totalBlocking = new AtomicLong(); private boolean blocking; private final ThreadLocal<Long> startedAt = new ThreadLocal<Long>() { protected Long initialValue() { return 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.register(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) { Action<Chain> handlers = new ChainAction() { protected void execute() { handler(new Handler() { public void handle(final Context context) throws Exception { context.addInterceptor(new ProcessingTimingInterceptor(context.getRequest()), new Action<Execution>() { public void execute(Execution execution) { context.next(); } }); } }); handler(new Handler() { public void handle(final Context context) throws Exception { Thread.currentThread().sleep(100); context .blocking(new Callable<String>() { public String call() throws Exception { Thread.currentThread().sleep(100); return "foo"; } }) .then(new Action<String>() { public void execute(String string) throws Exception { Thread.currentThread().sleep(100); context.render(string); } }); } }); } }; HandlingResult result = UnitTest.handle(handlers, Actions.noop()); assert result.rendered(String.class).equals("foo"); Timer timer = result.getRequestRegistry().get(Timer.class); assert timer.getBlockingTime() >= 100; assert timer.getComputeTime() >= 200; } }For other types of executions (e.g. background jobs), the interceptor can be registered via
Context.addInterceptor(ExecInterceptor, ratpack.func.Action)
.Modifier and Type | Interface and Description |
---|---|
static class |
ExecInterceptor.ExecType
The execution type (i.e.
|
Modifier and Type | Method and Description |
---|---|
void |
intercept(ExecInterceptor.ExecType execType,
Runnable continuation)
Intercepts the “rest” of the execution on the current thread.
|
void intercept(ExecInterceptor.ExecType execType, Runnable continuation)
The given Runnable
argument represents the rest of the execution to occur on this thread.
This does not necessarily mean the rest of the execution until the work (e.g. responding to a request) is complete.
Execution may involve multiple parallel (but not concurrent) threads of execution because of blocking IO or asynchronous APIs.
All exceptions thrown by this method will be ignored.
execType
- indicates whether this is a compute (e.g. request handling) or blocking IO threadcontinuation
- the “rest” of the execution