com.gh.bmd.jrt.routine.Routine Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jroutine Show documentation
Show all versions of jroutine Show documentation
Parallel programming on the go
/*
* 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 com.gh.bmd.jrt.routine;
import com.gh.bmd.jrt.channel.OutputChannel;
import com.gh.bmd.jrt.channel.ParameterChannel;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* This interface defines the main component of this framework.
*
* The interface takes inspiration from the Go routines, where functions are executed
* asynchronously and communicate with the external world only through channels. Being Java a
* strictly object oriented programming language, the routine itself must be an object based on
* logic implemented in other objects.
*
* The framework includes a routine class based on the implementation of an invocation interface.
* Invocation objects are dynamically instantiated when needed, effectively mimicking the temporary
* scope of a function call.
* The paradigm is based on input, result and output channels. A routine can be invoked in
* different ways (as explained below). Each routine invocation returns an input channel through
* which the caller can pass the input parameters. When all the parameters has been passed, the
* input channel is closed and returns the output channel from which to read the invocation
* results. At the same time a result channel is passed to the invocation implementation, so that
* the output computed from the input parameters can be published outside.
* The advantage of this approach is that the invocation flow can be run in steps, allowing for
* continuous streaming of the input data and for abortion in the middle of the execution, without
* blocking the running thread for the whole duration of the asynchronous invocation.
* In fact, each channel can abort the execution at any time.
*
* The implementing class must provides an automatic synchronization of the invocation member
* fields, though, in order to avoid concurrency issues, data passed through the routine channels
* should be immutable or, at least, never shared inside and outside the routine.
* Moreover, it is possible to recursively call the same or another routine from inside a routine
* invocation in a safe way. Nevertheless, it is always advisable to never perform blocking calls
* (such as: reading data from an output channel) in the middle of an execution, since the use
* of shared runner instances may lead to unexpected deadlocks. In facts, to prevent deadlock or
* starvation issues, it is encouraged the use of finite timeouts when performing blocking calls.
*
* The routine object provides three different ways to invoke an execution:
*
* Synchronous invocation
* The routine starts an invocation employing a synchronous runner. The result is similar to a
* classic method call where the processing completes as soon as the function exits.
*
* Asynchronous invocation
* The routine starts an invocation employing an asynchronous runner. In this case the processing
* happens in a different thread, while the calling process may go on with its own execution and
* perform other tasks. The invocation results can be collected at any time through the output
* channel methods.
*
* Parallel invocation
* Processing parallelization is the key to leverage the power of multi-core machines. In order to
* achieve it, the input data must be divided into subsets which are then processed on different
* threads.
* A routine object provides a convenient way to start an invocation which in turn spawns another
* invocation for each input passed. This particular type of invocation obviously produces
* meaningful results only for routines which takes a single input parameter and computes the
* relative output results.
*
* It is worth noting how the framework has been designed only through interfaces, so that,
* as far as the implementation honors the specific contracts, it is possible to seamlessly combine
* different routine implementations. Even the ones coming from third party libraries.
*
* Created by davide on 9/7/14.
*
* @param the input data type.
* @param