All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.atleon.core.AloOps Maven / Gradle / Ivy
package io.atleon.core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.SynchronousSink;
import reactor.util.context.ContextView;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* Common utility methods associated with operations on Alo and related components
*/
final class AloOps {
private static final Logger LOGGER = LoggerFactory.getLogger(AloOps.class);
private AloOps() {
}
public static BiConsumer, SynchronousSink>>
filteringHandler(Predicate super T> predicate, Consumer super Alo> negativeConsumer) {
return (alo, sink) -> {
Boolean result = null;
try {
result = alo.supplyInContext(() -> predicate.test(alo.get()));
} catch (Throwable error) {
processFailureOrNacknowledge(sink, alo, error);
}
if (result != null) {
if (result) {
sink.next(alo);
} else {
handleDiscard(sink.contextView(), alo, negativeConsumer);
}
}
};
}
public static BiConsumer, SynchronousSink>>
typeFilteringHandler(Class clazz, Consumer super Alo> negativeConsumer) {
return (alo, sink) -> {
if (clazz.isAssignableFrom(alo.get().getClass())) {
sink.next((Alo) alo);
} else {
handleDiscard(sink.contextView(), alo, negativeConsumer);
}
};
}
public static BiConsumer, SynchronousSink>>
mappingHandler(Function super T, ? extends R> mapper) {
return (alo, sink) -> {
Alo result = null;
try {
// Note: mapping is not invoked with *InContext since we're delegating to Alo anyway
result = Objects.requireNonNull(alo.map(mapper), "Alo implementation returned null mapping");
} catch (Throwable error) {
processFailureOrNacknowledge(sink, alo, error);
}
if (result != null) {
sink.next(result);
}
};
}
public static BiConsumer, SynchronousSink>>
mappingPresentHandler(Function super T, Optional extends R>> mapper, Consumer super Alo> absentConsumer) {
return (alo, sink) -> {
Alo> result = null;
try {
// Note: mapping is not invoked with *InContext since we're delegating to Alo anyway
result = Objects.requireNonNull(alo.map(mapper), "Alo implementation returned null mapping");
} catch (Throwable error) {
processFailureOrNacknowledge(sink, alo, error);
}
if (result != null) {
if (result.get().isPresent()) {
sink.next(PresentAlo.wrap(result));
} else {
absentConsumer.accept(alo);
}
}
};
}
public static BiConsumer, SynchronousSink>>
consumingHandler(Consumer super T> consumer, Consumer super Alo> afterSuccessConsumer) {
return (alo, sink) -> {
boolean consumed = false;
try {
alo.runInContext(() -> consumer.accept(alo.get()));
consumed = true;
} catch (Throwable error) {
processFailureOrNacknowledge(sink, alo, error);
}
if (consumed) {
afterSuccessConsumer.accept(alo);
}
};
}
public static BiConsumer, SynchronousSink>>
failureProcessingHandler(Predicate super T> isFailure, Function super T, ? extends Throwable> errorExtractor) {
return (alo, sink) -> {
T t = alo.get();
if (isFailure.test(t)) {
processFailure(sink, alo, errorExtractor.apply(t), () -> sink.next(alo));
} else {
sink.next(alo);
}
};
}
public static Alo> fanIn(List> alos) {
Alo firstAlo = alos.get(0);
if (alos.size() == 1) {
return firstAlo.map(Collections::singletonList);
} else {
return firstAlo.fanInPropagator(alos).create(
alos.stream().map(Alo::get).collect(Collectors.toList()),
combineAcknowledgers(alos.stream().map(Alo::getAcknowledger).collect(Collectors.toList())),
combineNacknowledgers(alos.stream().map(Alo::getNacknowledger).collect(Collectors.toList()))
);
}
}
private static void processFailureOrNacknowledge(SynchronousSink> sink, Alo> alo, Throwable error) {
processFailure(sink, alo, error, () -> Alo.nacknowledge(alo, error));
}
private static void processFailure(SynchronousSink> sink, Alo> alo, Throwable error, Runnable unprocessedFallback) {
if (!AloFailureStrategy.choose(sink).process(alo, error, sink::error)) {
unprocessedFallback.run();
}
}
private static void handleDiscard(ContextView contextView, Alo alo, Consumer super Alo> afterHandle) {
try {
alo.runInContext(() -> DiscardHook.choose(contextView).accept(alo.get()));
} catch (Throwable error) {
LOGGER.warn("Error in discard hook", error);
} finally {
afterHandle.accept(alo);
}
}
private static Runnable combineAcknowledgers(Iterable extends Runnable> acknowledgers) {
return () -> acknowledgers.forEach(Runnable::run);
}
private static Consumer super Throwable>
combineNacknowledgers(Iterable extends Consumer super Throwable>> nacknowledgers) {
return error -> nacknowledgers.forEach(nacknowledger -> nacknowledger.accept(error));
}
}