
delight.concurrency.Concurrent Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of delight-concurrency Show documentation
Show all versions of delight-concurrency Show documentation
An abstract and lightweight definition of concurrency fundamentals.
The newest version!
package delight.concurrency;
import delight.async.Operation;
import delight.async.Value;
import delight.async.callbacks.SimpleCallback;
import delight.async.callbacks.ValueCallback;
import delight.concurrency.wrappers.SimpleExecutor;
import delight.functional.Closure;
import java.util.ArrayList;
import java.util.List;
public class Concurrent {
/**
* Perform these operations sequentially but their own threads to prevent
* stack overflows.
*
* @param operations
* @param concurrency
* @param callback
*/
public static void sequential(final List> operations, final Concurrency concurrency,
final ValueCallback> callback) {
final Value executor = new Value(null);
sequentialInt(operations, 0, new ArrayList(operations.size()), concurrency, executor, callback);
}
public static void sequential(final List> operations, final Closure asyncExecutor,
final ValueCallback> callback) {
sequentialInt(operations, 0, new ArrayList(operations.size()), asyncExecutor, callback);
}
public static void sequential(final List> operations, final ValueCallback> callback) {
sequentialInt(operations, 0, new ArrayList(operations.size()), new Closure() {
@Override
public void apply(final Runnable o) {
o.run();
}
}, callback);
}
private static void sequentialInt(final List> operations, final int idx, final List results,
final Closure asyncExecutor, final ValueCallback> callback) {
if (idx >= operations.size()) {
callback.onSuccess(results);
return;
}
operations.get(idx).apply(new ValueCallback() {
@Override
public void onFailure(final Throwable t) {
callback.onFailure(t);
}
@Override
public void onSuccess(final R value) {
if (results.size() > idx) {
callback.onFailure(
new Exception("Callback for operation was already called: " + operations.get(idx)));
return;
}
results.add(value);
if (idx == 0 || idx % 4 != 0) {
sequentialInt(operations, idx + 1, results, asyncExecutor, callback);
return;
}
asyncExecutor.apply(new Runnable() {
@Override
public void run() {
sequentialInt(operations, idx + 1, results, asyncExecutor, callback);
}
});
}
});
}
private static void sequentialInt(final List> operations, final int idx, final List results,
final Concurrency concurrency, final Value executor,
final ValueCallback> callback) {
if (idx >= operations.size()) {
final SimpleExecutor exc = executor.get();
if (exc == null) {
callback.onSuccess(results);
return;
}
exc.shutdown(new SimpleCallback() {
@Override
public void onFailure(final Throwable t) {
callback.onFailure(t);
}
@Override
public void onSuccess() {
callback.onSuccess(results);
}
});
return;
}
final Value failureReceived = new Value(false);
final Value successReceived = new Value(false);
operations.get(idx).apply(new ValueCallback() {
@Override
public void onFailure(final Throwable t) {
if (successReceived.get()) {
throw new RuntimeException("Cannot process failure callback <" + t.getMessage() + "> for operation "
+ operations.get(idx) + ". Success already received.", t);
}
if (failureReceived.get()) {
System.err.println("Cannot process failure callback for operation " + operations.get(idx)
+ ". Failure already received.\n Failure which cannot be processed:\n <" + t.getMessage()
+ ">");
return;
}
failureReceived.set(true);
callback.onFailure(t);
}
@Override
public void onSuccess(final R value) {
if (successReceived.get()) {
throw new RuntimeException("Cannot process success callback for operation " + operations.get(idx)
+ ". Success already received.");
}
if (failureReceived.get()) {
throw new RuntimeException("Cannot process success callback for operation " + operations.get(idx)
+ ". Failure already received.");
}
successReceived.set(true);
if (results.size() > idx) {
callback.onFailure(
new Exception("Callback for operation was already called: " + operations.get(idx)));
return;
}
results.add(value);
if (idx == 0 || idx % 4 != 0) {
sequentialInt(operations, idx + 1, results, concurrency, executor, callback);
return;
}
SimpleExecutor exc = executor.get();
if (exc == null) {
// System.out.println("Create dedicated executor.");
exc = concurrency.newExecutor().newAsyncExecutor(this);
executor.set(exc);
}
exc.execute(new Runnable() {
@Override
public void run() {
sequentialInt(operations, idx + 1, results, concurrency, executor, callback);
}
});
}
});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy