
net.e6tech.elements.network.cluster.catalyst.Catalyst Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2015-2019 Futeh Kao
*
* 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 net.e6tech.elements.network.cluster.catalyst;
import net.e6tech.elements.common.util.SystemException;
import net.e6tech.elements.common.util.concurrent.Async;
import net.e6tech.elements.common.federation.Registry;
import net.e6tech.elements.network.cluster.catalyst.dataset.*;
import net.e6tech.elements.network.cluster.catalyst.scalar.Scalar;
import net.e6tech.elements.network.cluster.catalyst.transform.Series;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Function;
@SuppressWarnings({"unchecked", "squid:S00119", "squid:S1700"})
public class Catalyst {
private Registry registry;
private long waitTime = 30000L;
private String qualifier = "";
private Class reactorClass;
public Catalyst(String qualifier, Class reactorClass, Registry registry) {
this.qualifier = qualifier;
this.registry = registry;
this.reactorClass = reactorClass;
}
public long getWaitTime() {
return waitTime;
}
public void setWaitTime(long waitTime) {
this.waitTime = waitTime;
}
public String getQualifier() {
return qualifier;
}
public Registry getRegistry() {
return registry;
}
public Builder builder(DataSet dataSet) {
return new Builder<>(this, dataSet);
}
public Builder builder(Series series, DataSet dataSet) {
return new Builder<>(this, series, dataSet);
}
public U scalar(Scalar scalar, DataSet dataSet) {
Collection result = collect(scalar, dataSet);
Async async = registry.async(qualifier, reactorClass, waitTime, Registry.Routing.local);
Series emptySeries = new Series<>();
Scalar copy;
try {
List> segList = new ArrayList<>();
segList.add(reactor -> result.stream());
Segments segments = new Segments<>(this, segList);
copy = (Scalar) scalar.gatherer();
copy.setSeries(emptySeries.allocate(segments));
} catch (Exception e) {
throw new SystemException(e);
}
return async.apply(p -> p.apply(copy))
.toCompletableFuture().join();
}
public Collection collect(Scalar scalar, DataSet dataSet) {
List> workLoad = prepareWork(dataSet,
segments -> {
try {
Scalar copy = scalar.clone();
copy.setSeries(scalar.getSeries().allocate(segments));
return copy;
} catch (Exception e) {
throw new SystemException(e);
}
});
List result = new ArrayList<>();
for (Work work: workLoad) {
work.start();
}
for (Work work: workLoad) {
result.add(work.value());
}
return result;
}
@SuppressWarnings("squid:S1596")
public void run(Runnable ... runnables) {
RemoteDataSet> dataSet = new RemoteDataSet<>();
for (Runnable runnable : runnables)
dataSet.add(reactor -> {
runnable.run();
return Collections.EMPTY_LIST.stream();
});
transform(new Series<>(), dataSet);
}
@SuppressWarnings("squid:S1596")
public void run(Consumer ... consumers) {
RemoteDataSet> dataSet = new RemoteDataSet<>();
for (Consumer consumer : consumers)
dataSet.add(reactor -> {
consumer.accept(reactor);
return Collections.EMPTY_LIST.stream();
});
transform(new Series<>(), dataSet);
}
public Collection transform(Series series, DataSet dataSet) {
List>> workLoad =
prepareWork(dataSet, series::allocate);
for (Work> work: workLoad) {
work.start();
}
Gatherer gatherer = series.gatherer();
for (Work> work: workLoad) {
gatherer.gather(work.value());
}
return gatherer.collection;
}
private List> prepareWork(DataSet dataSet, Function, SerializableFunction extends Reactor, O>> work) {
Segments segments = dataSet.segment(this);
List> workLoad = new ArrayList<>();
for (int i = 0; i < segments.size(); i++) {
workLoad.add(new Work(registry.async(qualifier, reactorClass, waitTime), segments, work));
}
return workLoad;
}
private static class Work {
Async async;
Segments segments;
CompletableFuture future;
Function, SerializableFunction extends Reactor, R>> work;
SerializableFunction extends Reactor, R> function;
Work(Async async, Segments segments, Function, SerializableFunction extends Reactor, R>> work) {
this.async = async;
this.segments = segments;
this.work = work;
}
void start() {
if (function == null) {
// this will create a Series, Scalar or other Function for submiting to Reactor
// the result should contain a segment removed from segments. Therefore, work.apply should only be called once.
function = work.apply(segments);
}
future = async.apply(reactor -> reactor.apply(function)).toCompletableFuture();
}
R value() {
try {
return future.join();
} catch (Exception ex) {
start();
return future.join();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy