Errors during the data mining are now forwarded and logged

This improves the visibilities of failures, because they aren't hided by
the multithreading anymore.
This commit is contained in:
Lennart Hensler committed 2014-04-03 17:34:55 +02:00
1 parent 62267515c4
commit 6fb6345ee9
15 files changed
+89 -2

No files matched your search

@@ -166,6 +166,9 @@ public class TestProcessorQuery {
receivedElementOrFinished = true; receivedElementOrFinished = true;
} }
@Override @Override
public void onFailure(Throwable failure) {
}
@Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
receivedElementOrFinished = true; receivedElementOrFinished = true;
} }
@@ -57,6 +57,9 @@ public class TestAbstractFilteringRetrievalProcessor {
} }
} }
@Override @Override
public void onFailure(Throwable failure) {
}
@Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
} }
@Override @Override
@@ -52,6 +52,8 @@ public class TestAbstractParallelProcessorFinishing {
@Override @Override
public void onElement(Integer element) { } public void onElement(Integer element) { }
@Override @Override
public void onFailure(Throwable failure) { }
@Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
receiverWasToldToFinish = true; receiverWasToldToFinish = true;
} }
@@ -29,6 +29,9 @@ public class TestAbstractParallelProcessorWithManySimpleInstructions {
incrementSum(element); incrementSum(element);
} }
@Override @Override
public void onFailure(Throwable failure) {
}
@Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
receiverWasToldToFinish = true; receiverWasToldToFinish = true;
} }
@@ -24,6 +24,9 @@ public class TestAbstractProcessor {
public void onElement(Integer element) { public void onElement(Integer element) {
} }
@Override @Override
public void onFailure(Throwable failure) {
}
@Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
receiverWasToldToFinish = true; receiverWasToldToFinish = true;
} }
@@ -97,6 +97,9 @@ public class TestFilteringProcessors {
receivedElements.put(element, elementAmount); receivedElements.put(element, elementAmount);
} }
@Override @Override
public void onFailure(Throwable failure) {
}
@Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
} }
@Override @Override
@@ -45,6 +45,9 @@ public class TestParallelExtractionProcessor {
receivedValues.put(element.getKey(), element.getDataEntry()); receivedValues.put(element.getKey(), element.getDataEntry());
} }
@Override @Override
public void onFailure(Throwable failure) {
}
@Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
} }
@Override @Override
@@ -37,6 +37,8 @@ public class TestParallelMultiDimensionalGroupingProcessor {
groupedElement = element; groupedElement = element;
} }
@Override @Override
public void onFailure(Throwable failure) { }
@Override
public void finish() throws InterruptedException { } public void finish() throws InterruptedException { }
@Override @Override
public void abort() { } public void abort() { }
@@ -31,6 +31,9 @@ public class TestAbstractStoringParallelAggregationProcessor {
receivedElement = element; receivedElement = element;
} }
@Override @Override
public void onFailure(Throwable failure) {
}
@Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
receiverWasToldToFinish = true; receiverWasToldToFinish = true;
} }
@@ -184,6 +184,9 @@ public class TestParallelDoubleAggregationProcessors {
receivedAggregations = element; receivedAggregations = element;
} }
@Override @Override
public void onFailure(Throwable failure) {
}
@Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
} }
@Override @Override
@@ -6,6 +6,16 @@ public interface Processor<InputType> {
public void onElement(InputType element); public void onElement(InputType element);
/**
* This method handles the throwing of Throwables, so they don't get lost because of the
* multi-threading.<br>
* The standard implementation would be a forwarding to the last processor,
* that collects the failures, until the processing is finished. Than the failures will be
* handled.
* @param failure
*/
void onFailure(Throwable failure);
/** /**
* Tells this Processor, that there will be no incoming data.<br /> * Tells this Processor, that there will be no incoming data.<br />
* The called Processor will finish his work and call <code>finish()</code> on all subsequent processors. * The called Processor will finish his work and call <code>finish()</code> on all subsequent processors.
@@ -1,6 +1,8 @@
package com.sap.sse.datamining.impl; package com.sap.sse.datamining.impl;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Timer; import java.util.Timer;
@@ -93,6 +95,8 @@ public class ProcessorQuery<AggregatedType, DataSourceType> implements Query<Agg
}); });
waitTillWorkIsDone(timeoutInMillis); waitTillWorkIsDone(timeoutInMillis);
final long endTime = System.nanoTime(); final long endTime = System.nanoTime();
logOccuredFailures();
long calculationTimeInNanos = endTime - startTime; long calculationTimeInNanos = endTime - startTime;
AdditionalResultDataBuilder additionalDataBuilder = new SumBuildingAndOverwritingResultDataBuilder(); AdditionalResultDataBuilder additionalDataBuilder = new SumBuildingAndOverwritingResultDataBuilder();
@@ -101,6 +105,12 @@ public class ProcessorQuery<AggregatedType, DataSourceType> implements Query<Agg
return new QueryResultImpl<>(results, additionalDataBuilder.build(calculationTimeInNanos, stringMessages, locale)); return new QueryResultImpl<>(results, additionalDataBuilder.build(calculationTimeInNanos, stringMessages, locale));
} }
private void logOccuredFailures() {
for (Throwable failure : resultReceiver.getOccuredFailures()) {
LOGGER.log(Level.SEVERE, "An error occured during the processing of an instruction: ", failure);
}
}
private void waitTillWorkIsDone(long timeoutInMillis) throws InterruptedException, TimeoutException { private void waitTillWorkIsDone(long timeoutInMillis) throws InterruptedException, TimeoutException {
setUpTimeoutTimer(timeoutInMillis); setUpTimeoutTimer(timeoutInMillis);
synchronized (monitorObject) { synchronized (monitorObject) {
@@ -138,10 +148,12 @@ public class ProcessorQuery<AggregatedType, DataSourceType> implements Query<Agg
private final ReentrantLock resultsLock; private final ReentrantLock resultsLock;
private Map<GroupKey, AggregatedType> results; private Map<GroupKey, AggregatedType> results;
private List<Throwable> occuredFailures;
public ProcessResultReceiver() { public ProcessResultReceiver() {
resultsLock = new ReentrantLock(); resultsLock = new ReentrantLock();
results = new HashMap<>(); results = new HashMap<>();
occuredFailures = new ArrayList<>();
} }
@Override @Override
@@ -153,6 +165,11 @@ public class ProcessorQuery<AggregatedType, DataSourceType> implements Query<Agg
resultsLock.unlock(); resultsLock.unlock();
} }
} }
@Override
public void onFailure(Throwable failure) {
occuredFailures.add(failure);
}
@Override @Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
@@ -164,12 +181,17 @@ public class ProcessorQuery<AggregatedType, DataSourceType> implements Query<Agg
@Override @Override
public void abort() { public void abort() {
results = null; results = new HashMap<>();
occuredFailures = new ArrayList<>();
} }
public Map<GroupKey, AggregatedType> getResult() { public Map<GroupKey, AggregatedType> getResult() {
return results; return results;
} }
public List<Throwable> getOccuredFailures() {
return occuredFailures;
}
@Override @Override
public AdditionalResultDataBuilder getAdditionalResultData(AdditionalResultDataBuilder additionalDataBuilder) { public AdditionalResultDataBuilder getAdditionalResultData(AdditionalResultDataBuilder additionalDataBuilder) {
@@ -46,7 +46,7 @@ public abstract class AbstractPartitioningParallelProcessor<InputType, WorkingTy
} }
} catch (Exception e) { } catch (Exception e) {
if (!gotAborted || !(e instanceof InterruptedException)) { if (!gotAborted || !(e instanceof InterruptedException)) {
LOGGER.log(Level.FINEST, "An error occured during the processing of an instruction: ", e); onFailure(e);
} }
} finally { } finally {
AbstractPartitioningParallelProcessor.this.unfinishedInstructionsCounter.decrement(); AbstractPartitioningParallelProcessor.this.unfinishedInstructionsCounter.decrement();
@@ -88,6 +88,13 @@ public abstract class AbstractPartitioningParallelProcessor<InputType, WorkingTy
protected abstract Iterable<WorkingType> partitionElement(InputType element); protected abstract Iterable<WorkingType> partitionElement(InputType element);
@Override
public void onFailure(Throwable failure) {
for (Processor<ResultType> resultReceiver : resultReceivers) {
resultReceiver.onFailure(failure);
}
}
@Override @Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
sleepUntilAllInstructionsFinished(); sleepUntilAllInstructionsFinished();
@@ -20,6 +20,13 @@ public abstract class AbstractProcessor<InputType, ResultType> implements Proces
ResultType result = processElement(element); ResultType result = processElement(element);
forwardResultToTheReceivers(result); forwardResultToTheReceivers(result);
} }
@Override
public void onFailure(Throwable failure) {
for (Processor<ResultType> resultReceiver : resultReceivers) {
resultReceiver.onFailure(failure);
}
}
private void forwardResultToTheReceivers(ResultType result) { private void forwardResultToTheReceivers(ResultType result) {
for (Processor<ResultType> resultReceiver : resultReceivers) { for (Processor<ResultType> resultReceiver : resultReceivers) {
@@ -1,10 +1,12 @@
package com.sap.sse.datamining.impl.functions; package com.sap.sse.datamining.impl.functions;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@@ -129,9 +131,12 @@ public class SimpleFunctionRegistry implements FunctionRegistry {
private class FunctionsReceiver implements Processor<Collection<Function<?>>> { private class FunctionsReceiver implements Processor<Collection<Function<?>>> {
private final Lock functionsRegistrationLock; private final Lock functionsRegistrationLock;
private final List<Throwable> occuredFailures;
public FunctionsReceiver() { public FunctionsReceiver() {
functionsRegistrationLock = new ReentrantLock(); functionsRegistrationLock = new ReentrantLock();
occuredFailures = new ArrayList<>();
} }
@Override @Override
@@ -143,9 +148,17 @@ public class SimpleFunctionRegistry implements FunctionRegistry {
functionsRegistrationLock.unlock(); functionsRegistrationLock.unlock();
} }
} }
@Override
public void onFailure(Throwable failure) {
occuredFailures.add(failure);
}
@Override @Override
public void finish() throws InterruptedException { public void finish() throws InterruptedException {
for (Throwable failure : occuredFailures) {
LOGGER.log(Level.SEVERE, "An error occured during the processing of an instruction: ", failure);
}
} }
@Override @Override