@FunctionalInterface
public interface ExecInterceptor
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.Assert.assertEquals;
import static org.junit.Assert.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);
}
}
Modifier and Type | Interface and Description |
---|---|
static class |
ExecInterceptor.ExecType
The execution type (i.e.
|
Modifier and Type | Method and Description |
---|---|
void |
intercept(Execution execution,
ExecInterceptor.ExecType execType,
Block executionSegment)
Intercepts the execution of an execution segment.
|
void intercept(Execution execution, ExecInterceptor.ExecType execType, Block executionSegment) throws java.lang.Exception
The execution segment argument represents a unit of work of the execution.
Implementations MUST invoke execute()
on the given execution segment block.
execution
- the execution that this segment belongs toexecType
- indicates whether this segment is execution on a compute or blocking threadexecutionSegment
- the execution segment that is to be executedjava.lang.Exception
- any