public interface ExecControl
import ratpack.exec.ExecControl;
import ratpack.exec.ExecController;
import ratpack.exec.Promise;
import ratpack.test.handling.RequestFixture;
import ratpack.test.handling.HandlingResult;
import static org.junit.Assert.assertEquals;
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(f -> f.success(lower.toUpperCase()));
}
}
public static void main(String[] args) throws Exception {
HandlingResult result = RequestFixture.requestFixture().handleChain(chain -> {
ExecControl control = chain.getRegistry().get(ExecController.class).getControl();
AsyncUpperCaseService service = new AsyncUpperCaseService(control);
chain.get(ctx -> service.toUpper("foo").then(ctx::render));
});
assertEquals("FOO", result.rendered(String.class));
}
}
Note: when using the Guice integration, the exec control is made available for injection.
Modifier and Type | Method and Description |
---|---|
void |
addInterceptor(ExecInterceptor execInterceptor,
Block continuation)
Adds an interceptor that wraps the rest of the current execution segment and all future segments of this execution.
|
<T> Promise<T> |
blocking(Callable<T> blockingOperation)
Performs a blocking operation on a separate thread, returning a promise for its value.
|
static ExecControl |
current()
Provides the execution control bound to the current thread.
|
ExecStarter |
exec()
Creates a new execution starter that can be used to initiate a new execution.
|
static ExecControl |
execControl()
An exec control that binds to the thread's execution on demand.
|
default <T> Promise<T> |
failedPromise(Throwable error)
Creates a failed promise with the given error.
|
ExecController |
getController() |
Execution |
getExecution() |
default void |
nest(Block nested,
Block then) |
default void |
nest(Block nested,
Block then,
Action<? super Throwable> onError) |
<T> Promise<T> |
promise(Action<? super Fulfiller<T>> action)
Creates a promise for an asynchronously created value.
|
default <T> Promise<T> |
promiseOf(T item)
Creates a promise for the given value.
|
<T> TransformablePublisher<T> |
stream(org.reactivestreams.Publisher<T> publisher)
Process streams of data asynchronously with non-blocking back pressure.
|
default <T> Promise<T> |
wrap(Factory<? extends Promise<T>> factory)
Executes the given promise producing factory, converting any thrown exception into a failed promise.
|
static ExecControl current() throws UnmanagedThreadException
This method will fail when called outside of a Ratpack compute thread as it relies on ExecController.require()
.
UnmanagedThreadException
static ExecControl execControl()
Unlike the current()
method, this method can be called outside of a Ratpack managed thread.
However, the methods of the returned exec control can only be called on managed threads.
If a method is called while not on a managed thread, a UnmanagedThreadException
will be thrown.
import ratpack.exec.ExecControl;
import ratpack.test.exec.ExecHarness;
import static org.junit.Assert.assertEquals;
public class Example {
// Get an exec control on a non managed thread (i.e. the JVM main thread)
public static ExecControl control = ExecControl.execControl();
public static void main(String... args) throws Exception {
String value = ExecHarness.yieldSingle(e ->
control.blocking(() -> "foo")
).getValue();
assertEquals("foo", value);
}
}
Execution getExecution() throws UnmanagedThreadException
UnmanagedThreadException
ExecController getController()
void addInterceptor(ExecInterceptor execInterceptor, Block continuation) throws Exception
The given action is executed immediately (i.e. as opposed to being queued to be executed as the next execution segment). Any code executed after a call to this method in the same execution segment WILL NOT be intercepted. Therefore, it is advisable to not execute any code after calling this method in a given execution segment.
See ExecInterceptor
for example use of an interceptor.
execInterceptor
- the execution interceptor to addcontinuation
- the rest of the code to be executedException
- any thrown by continuation
ExecInterceptor
<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.
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 promised valueaction
- an action that invokes an asynchronous API, forwarding the result to the given fulfillerFulfiller
,
Fulfillment
default <T> Promise<T> promiseOf(T item)
This method can be used when a promise is called for, but the value is immediately available.
T
- the type of promised valueitem
- the promised valuedefault <T> Promise<T> failedPromise(Throwable error)
This method can be used when a promise is called for, but the failure is immediately available.
T
- the type of promised valueerror
- the promise failuredefault <T> Promise<T> wrap(Factory<? extends Promise<T>> factory)
Can be used to wrap execution of promise returning functions that may themselves throw errors.
import ratpack.exec.Promise;
import ratpack.exec.ExecControl;
import ratpack.exec.ExecResult;
import ratpack.test.exec.ExecHarness;
import static org.junit.Assert.assertEquals;
public class Example {
public static Promise<String> someMethod() throws Exception {
throw new Exception("bang!");
}
public static void main(String... args) throws Exception {
ExecResult<String> result = ExecHarness.yieldSingle(e ->
e.wrap(() -> someMethod())
);
assertEquals("bang!", result.getThrowable().getMessage());
}
}
T
- the type of promised valuefactory
- the promise factoryExecStarter exec()
<T> TransformablePublisher<T> stream(org.reactivestreams.Publisher<T> publisher)
This method allows the processing of elements (onNext) or termination signals (onError, onComplete) to happen outside of the execution stack of the Publisher. In other words these "events" are executed asynchronously, on a Ratpack managed thread, without blocking the Publisher.
T
- the type of streamed elementspublisher
- the provider of a potentially unbounded number of sequenced elements, publishing them according to the demand
received from its Subscriber(s)