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

ratpack.exec.Execution 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 com.google.common.reflect.TypeToken;
import io.netty.channel.EventLoop;
import ratpack.exec.internal.ExecutionBacking;
import ratpack.func.Block;
import ratpack.registry.MutableRegistry;

import java.util.function.Supplier;

/**
 * A logical stream of execution, which is potentially serialized over many threads.
 * 

* Ratpack is non blocking. * This requires that IO and other blocking operations are performed asynchronously. * In completely synchronous execution, the thread and the call stack serve as the representation of a stream of execution, * with the execution being bound to a single thread exclusively for its entire duration. * The {@code Execution} concept in Ratpack brings some of the characteristics of the traditional single-thread exclusive model * to the asynchronous, non-exclusive, environment. *

* A well understood example of a logical stream of execution in the web application environment is the handling of a request. * This can be thought of as a single logical operation; the request comes in and processing happens until the response is sent back. * Many web application frameworks exclusively assign a thread to such a stream of execution, from a large thread pool. * If a blocking operation is performed during the execution, the thread sits waiting until it can continue (e.g. the IO completes, or the contended resource becomes available). * Thereby the segments of the execution are serialized and the call stack provides execution context. * Ratpack supports the non-blocking model, where threads do not wait. * Instead of threads waiting for IO or some future event, they are returned to the “pool” to be used by other executions (and therefore the pool can be smaller). * When the IO completes or the contended resource becomes available, execution continues with a new call stack and possibly on a different thread. *

* The execution object underpins an entire logical operation, even when that operation may be performed by multiple threads. *

* Importantly, it also serializes execution segments by way of the {@link Promise#of(Upstream)} method. * These methods are fundamentally asynchronous in that they facilitate performing operations where the result will arrive later without waiting for the result, * but are synchronous in the operations the perform are serialized and not executed concurrently or in parallel. * Crucially, this means that state that is local to an execution does not need to be thread safe. *

Executions and request handling

*

* The execution object actually underpins the {@link ratpack.handling.Context} objects that are used when handling requests. * It is rarely used directly when request handling, except when concurrency or parallelism is required to process data via the {@link Execution#fork()} method. * Moreover, it provides its own error handling and completion mechanisms. *

*/ public interface Execution extends MutableRegistry { /** * Provides the currently execution execution. *

* This method will fail when called outside of a Ratpack compute thread as it relies on {@link ExecController#require()}. * * @return the currently executing execution */ static Execution current() throws UnmanagedThreadException { return ExecutionBacking.require().getExecution(); } static ExecBuilder fork() throws UnmanagedThreadException { return current().getController().exec(); } /** * The execution controller that this execution is associated with. * * @return the execution controller that this execution is associated with */ ExecController getController(); EventLoop getEventLoop(); // TODO: this is not the right name. void onCleanup(AutoCloseable autoCloseable); /** * {@inheritDoc} */ @Override default Execution add(Class type, O object) { MutableRegistry.super.add(type, object); return this; } /** * {@inheritDoc} */ @Override default Execution add(TypeToken type, O object) { MutableRegistry.super.add(type, object); return this; } /** * {@inheritDoc} */ @Override default Execution add(Object object) { MutableRegistry.super.add(object); return this; } /** * {@inheritDoc} */ @Override default Execution addLazy(Class type, Supplier supplier) { MutableRegistry.super.addLazy(type, supplier); return this; } /** * {@inheritDoc} */ @Override Execution addLazy(TypeToken type, Supplier supplier); /** * 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, Block continuation) throws Exception; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy