public interface ExecControl
import ratpack.exec.ExecControl; import ratpack.exec.Promise; import ratpack.exec.Fulfillment; import ratpack.handling.Handler; import ratpack.handling.Context; import ratpack.handling.ChainAction; import ratpack.func.Action; import ratpack.func.Actions; import ratpack.test.UnitTest; import ratpack.test.handling.HandlingResult; public class Example { public static class AsyncUpperCaseService { private final ExecControl control; public AsyncUpperCaseService(ExecControl control) { this.control = control; } public Promise<String> toUpper(final String lower) { return control.promise(new Fulfillment<String>() { protected void execute() { success(lower.toUpperCase()); } }); } } public static class ServiceUsingHandler implements Handler { private final AsyncUpperCaseService service; public ServiceUsingHandler(AsyncUpperCaseService service) { this.service = service; } public void handle(final Context context) { service.toUpper("foo").then(new Action<String>() { public void execute(String string) { context.render(string); } }); } } public static void main(String[] args) { HandlingResult result = UnitTest.handle( new ChainAction() { protected void execute() { ExecControl control = getLaunchConfig().getExecController().getControl(); AsyncUpperCaseService service = new AsyncUpperCaseService(control); Handler handler = new ServiceUsingHandler(service); get(handler); } }, Actions.noop() ); assert result.rendered(String.class).equals("FOO"); } }
Note: when using the Guice integration, the exec control is made available for injection.
Modifier and Type | Method and Description |
---|---|
<T> Promise<T> |
blocking(Callable<T> blockingOperation)
Performs a blocking operation on a separate thread, returning a promise for its value.
|
void |
fork(Action<? super Execution> action)
Forks a new execution on a separate thread.
|
<T> Promise<T> |
promise(Action<? super Fulfiller<T>> action)
Creates a promise for an asynchronously created value.
|
<T> Promise<T> blocking(Callable<T> blockingOperation)
This method should be used to perform blocking IO, or to perform any operation that synchronously waits for something to happen.
The given blockingOperation
will be performed on a thread from a special thread pool for such operations
(i.e. not a thread from the main compute event loop).
The operation should do as little computation as possible. It should just perform the blocking operation and immediately return the result. Performing computation during the operation will degrade performance.
This method is just a specialization of promise(ratpack.func.Action<? super ratpack.exec.Fulfiller<T>>)
, and shares all of the same semantics with regard to
execution binding and execution-on-promise-subscription.
import ratpack.launch.LaunchConfigBuilder; import ratpack.func.Action; import ratpack.exec.Execution; import ratpack.exec.ExecController; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; public class Example { public static void main(String[] args) throws InterruptedException { ExecController controller = LaunchConfigBuilder.noBaseDir().build().getExecController(); final CountDownLatch latch = new CountDownLatch(1); controller.start(new Action<Execution>() { public void execute(Execution execution) { execution .blocking(new Callable<String>() { public String call() { // perform a blocking op, e.g. a database call, filesystem read etc. return "foo"; } }) .then(new Action<String>() { public void execute(String string) { // do something with the value that was obtained from a blocking operation latch.countDown(); } }); } }); latch.await(); } }
T
- the type of value created by the operationblockingOperation
- the operation that blocks<T> Promise<T> promise(Action<? super Fulfiller<T>> action)
This method can be used to integrate with APIs that produce values asynchronously.
The asynchronous API should be invoked during the execute method of the action given to this method.
The result of the asynchronous call is then given to the Fulfiller
that the action is given.
T
- the type of valueaction
- an action that invokes an asynchronous API, forwarding the result to the given fulfiller.Fulfiller
,
Fulfillment
void fork(Action<? super Execution> action)
This is similar to using new Thread().run()
except that the action will be executed
on a Ratpack managed thread, and will use Ratpack's execution semantics.
This is functionally equivalent to ExecController.start(ratpack.func.Action)
.
action
- the initial execution segment