All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ratpack.exec.ExecControl Maven / Gradle / Ivy

There is a newer version: 2.0.0-rc-1
Show newest version
/*
 * Copyright 2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ratpack.exec;

import org.reactivestreams.Publisher;
import ratpack.func.Action;
import ratpack.func.NoArgAction;
import ratpack.stream.TransformablePublisher;

import java.util.concurrent.Callable;

/**
 * Provides methods for controlling execution(i.e. blocking, forking and calling async API), independent of the current execution.
 *
 * 
{@code
 * 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 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. */ public interface ExecControl { /** * Provides the execution control bound to the current thread. *

* This method will fail when called outside of a Ratpack compute thread as it relies on {@link ExecController#require()}. * * @return the execution control bound to the current thread */ static ExecControl current() { return ExecController.require().getControl(); } Execution getExecution(); ExecController getController(); /** * Adds an interceptor that wraps the rest of the current execution segment and all future segments of this execution. *

* 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 {@link ExecInterceptor} for example use of an interceptor. * * @param execInterceptor the execution interceptor to add * @param continuation the rest of the code to be executed * @throws Exception any thrown by {@code continuation} * @see ExecInterceptor */ void addInterceptor(ExecInterceptor execInterceptor, NoArgAction continuation) throws Exception; /** * Performs a blocking operation on a separate thread, returning a promise for its value. *

* This method should be used to perform blocking IO, or to perform any operation that synchronously waits for something to happen. * The given {@code 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 {@link #promise}, and shares all of the same semantics with regard to * execution binding and execution-on-promise-subscription. * * @param blockingOperation the operation that blocks * @param the type of value created by the operation * @return a promise for the return value of the given blocking operation */ Promise blocking(Callable blockingOperation); /** * Creates a promise for an asynchronously created value. *

* 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 {@link Fulfiller} that the action is given. * * @param action an action that invokes an asynchronous API, forwarding the result to the given fulfiller * @param the type of promised value * @return a promise for the asynchronously created value * @see Fulfiller * @see Fulfillment */ Promise promise(Action> action); default Promise promiseOf(T item) { return promise(f -> f.success(item)); } /** * Creates a new execution starter that can be used to initiate a new execution. * * @return an execution starter that can be used to configure and start a new execution. */ ExecStarter exec(); /** * Process streams of data asynchronously with non-blocking back pressure. *

* 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. * * @param publisher the provider of a potentially unbounded number of sequenced elements, publishing them according to the demand * received from its Subscriber(s) * @return effectively the given publisher, emitting each “event” as an execution segment of the current execution * @param the type of streamed elements */ TransformablePublisher stream(Publisher publisher); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy