The Mister Spex Executor contains a small, extensible library for execution Java methods to retry failing operations, measure the execution time or support refactoring in production.
Parts of the Mister Spex Scientist based on the ideas of the Github Scientist implementation.
The implementation is similar to Scientist4J but has no dependencies to external libraries.
Additionaly: for the Mister Spex Scientist implementation it is not required to run as a Singleton. For this reason you are responsible for collecting and processing the execution metrics. Implementation also delegates the comparison of results to external solutions. We believe this gives the you more freedom to use the API in your environment.
Use the following Maven dependency coordinates:
<dependency>
<groupId>io.misterspex</groupId>
<artifactId>misterspex-scientist</artifactId>
<version>1.0.0</version>
</dependency>
The main idea of the Scientist solution is testing software refactorings in production. Therefor a Scientist offers the execution of a candidate (the new implementation of a functionality) and the control, which should be the current production implementation of a functionality.
Main class of the Mister Spex Scientist implementation is io.misterspex.executor.scientist.Experiment
.
final Experiment<String> e = new Experiment<>();
final String result = e.execute(() -> "control", () -> "candidate");
Experiment
returns the result of the control function to the caller or throws the exception of the control execution.
This behavior may be configurable in future version.
The execution result of control and candidate together with additional metrics (execution time, eventual thrown exceptions…) are collected and published.
You collect this Result
by overwriting the publish(Result)
method.
publish
is always called before returning the execution function wether with the result or throwing an exception.
final Experiment<String> e = new Experiment<>() {
protected void publish(final Result result) {
logger.log(INFO, result);
}
};
final String result = e.execute(() -> "control", () -> "candidate");
With overwriting additional methods it is possible to control the behavior of the execution.
-
enabled()
- control thecandidate
execution. true by default. -
executionOrder()
- control wether execute control or candidate first. Fifty fifty mix by default.
Experiment
offers two types of constructors.
Such without offering an java.util.concurrent.ExecutorService
to supply and such with offering.
-
All executions are synchronous if you create an
Experiment
without anExecutorService
. -
All executions are asynchronous if you create an
Experiment
with anExecutorService
.
Note
|
If creating an ExecutorService with java.util.concurrent.Executors.newSingleThreadScheduledExecutor() the execution is again synchronous.
|
Basic executors are located in the io.misterspex.executor
package.
An executor can operate with Runnable
or Callable
implementations.
A Callable
execution will return a value where a Runnable
execution will return void
.
Currently two executors are implemented.
-
TimingExecutor
- measures the execution time of the executed function. It offers a method to query the time asDuration
. -
TrialExecutor
- tries to execute the function. If an execution fails, the executor retries the execution several times (configurable) before give up.
Both interfaces offers factory methods to generate instances of the executors. Such factory methods also offers factory methods to chain executors.
final TrialExecutor executor = TrialExecutor.of(2);
final String result = executor.execute(() -> doSomeStuff(data));
out.printf("Result %s - Trials: %d%n", result, executor.trials());
The snippet shows the creation and a TrialExecutor
, which executes the function doSomeStuff(data)
maximum 2 times.
The Mister Spex Executor uses a semantic naming pattern as described in Semantic Versioning 2.0.0.
Changing the minimum Java version is also a an incompatible API change and therefor will be a MAJOR change.
You are free to choose from one of the following licenses: