allow NBErrorHandler to map more detailed error names

This commit is contained in:
Jonathan Shook
2021-04-27 15:27:12 -05:00
parent 635abb93a5
commit c45662ab31
12 changed files with 40 additions and 32 deletions

View File

@@ -3,6 +3,7 @@ package io.nosqlbench.engine.api.activityapi.errorhandling.modular;
public class ErrorDetail {
public final Retry retryable;
public final int resultCode;
public final String name;
public boolean isRetryable() {
return retryable == Retry.DoRetry;
@@ -14,7 +15,8 @@ public class ErrorDetail {
Unset
}
public ErrorDetail(Retry retryable, int resultCode) {
public ErrorDetail(String name, Retry retryable, int resultCode) {
this.name = name;
this.resultCode = resultCode;
this.retryable = retryable;
}
@@ -23,18 +25,18 @@ public class ErrorDetail {
if (this.resultCode == resultCode) {
return this;
}
return new ErrorDetail(this.retryable, resultCode);
return new ErrorDetail(name, this.retryable, resultCode);
}
public ErrorDetail withRetryable() {
if (this.retryable == Retry.DoRetry) {
return this;
}
return new ErrorDetail(Retry.DoRetry, this.resultCode);
return new ErrorDetail(name, Retry.DoRetry, this.resultCode);
}
public static ErrorDetail OK = new ErrorDetail(Retry.Unset, 0);
public static ErrorDetail ERROR_NONRETRYABLE = new ErrorDetail(Retry.DoNotRetry, 127);
public static ErrorDetail ERROR_RETRYABLE = new ErrorDetail(Retry.DoRetry, 127);
public static ErrorDetail ERROR_UNKNOWN = new ErrorDetail(Retry.Unset, 127);
public static ErrorDetail OK = new ErrorDetail("OK",Retry.Unset, 0);
public static ErrorDetail ERROR_NONRETRYABLE = new ErrorDetail("ERROR_NONRETRYABLE",Retry.DoNotRetry, 127);
public static ErrorDetail ERROR_RETRYABLE = new ErrorDetail("ERROR_RETRYABLE",Retry.DoRetry, 127);
public static ErrorDetail ERROR_UNKNOWN = new ErrorDetail("ERROR_UNKNOWN",Retry.Unset, 127);
}

View File

@@ -11,5 +11,5 @@ public interface ErrorHandler {
* @param durationInNanos How long into an operation the error occured
* @return true if the operation should be retried, assuming retries available
*/
ErrorDetail handleError(Throwable t, long cycle, long durationInNanos, ErrorDetail detail);
ErrorDetail handleError(String name, Throwable t, long cycle, long durationInNanos, ErrorDetail detail);
}

View File

@@ -9,6 +9,7 @@ import io.nosqlbench.nb.api.config.params.NBParams;
import java.util.*;
import java.util.ServiceLoader.Provider;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -17,36 +18,43 @@ public class NBErrorHandler {
private final Supplier<ErrorMetrics> errorMetricsSupplier;
private final Supplier<String> configSpecSupplier;
private final Function<Throwable, String> namer;
private final Map<String, List<ErrorHandler>> handlerCache = new ConcurrentHashMap<>();
private final List<HandlerMapping> configs = new ArrayList<>();
public NBErrorHandler(Supplier<String> configSpecSupplier, Supplier<ErrorMetrics> metricsSupplier) {
this(configSpecSupplier, metricsSupplier, throwable -> throwable.getClass().getSimpleName());
}
public NBErrorHandler(Supplier<String> configSpecSupplier, Supplier<ErrorMetrics> metricsSupplier, Function<Throwable,String> namer) {
this.errorMetricsSupplier = metricsSupplier;
this.configSpecSupplier = configSpecSupplier;
this.namer = namer;
Arrays.stream(configSpecSupplier.get().split(";"))
.map(HandlerMapping::new)
.forEach(configs::add);
}
public ErrorDetail handleError(Throwable t, long cycle, long nanosIntoOp) {
String errorName = t.getClass().getSimpleName();
public ErrorDetail handleError(Throwable throwable, long cycle, long nanosIntoOp) {
String errorName = namer.apply(throwable);
// String errorName = t.getClass().getSimpleName();
List<ErrorHandler> handlers = handlerCache.get(errorName);
ErrorDetail detail = ErrorDetail.ERROR_NONRETRYABLE;
if (handlers == null) {
handlers = lookup(t);
handlerCache.put(t.getClass().getSimpleName(), handlers);
handlers = lookup(errorName);
handlerCache.put(errorName, handlers);
}
boolean retry = false;
for (ErrorHandler handler : handlers) {
detail = handler.handleError(t, cycle, nanosIntoOp, detail);
detail = handler.handleError(errorName, throwable, cycle, nanosIntoOp, detail);
}
return detail;
}
private synchronized List<ErrorHandler> lookup(Throwable t) {
String errorName = t.getClass().getSimpleName();
private synchronized List<ErrorHandler> lookup(String errorName) {
for (HandlerMapping config : configs) {
for (Pattern errorPattern : config.matchers) {
if (errorPattern.matcher(errorName).matches()) {
@@ -62,7 +70,7 @@ public class NBErrorHandler {
}
}
}
throw new RuntimeException("Unable to find a configured error handler for error '" + t.getClass().getSimpleName() + "'");
throw new RuntimeException("Unable to find a configured error handler for error '" + errorName + "'");
}
private ErrorHandler getHandler(Element cfg) {

View File

@@ -1,7 +1,5 @@
package io.nosqlbench.engine.api.activityapi.errorhandling.modular.handlers;
package io.nosqlbench.engine.api.activityapi.errorhandling.modular;
import io.nosqlbench.engine.api.activityapi.errorhandling.modular.ErrorDetail;
import io.nosqlbench.engine.api.activityapi.errorhandling.modular.ErrorHandler;
import io.nosqlbench.nb.annotations.Service;
import io.nosqlbench.nb.api.config.ConfigAware;
import io.nosqlbench.nb.api.config.ConfigModel;
@@ -15,7 +13,7 @@ public class ResultCode implements ErrorHandler, ConfigAware {
private byte code;
@Override
public ErrorDetail handleError(Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
public ErrorDetail handleError(String name, Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
return detail.withResultCode(code);
}

View File

@@ -14,8 +14,8 @@ public class CounterErrorHandler implements ErrorHandler, ErrorMetrics.Aware {
private ExceptionCountMetrics exceptionCountMetrics;
@Override
public ErrorDetail handleError(Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
exceptionCountMetrics.count(t);
public ErrorDetail handleError(String name, Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
exceptionCountMetrics.count(name);
return detail;
}

View File

@@ -18,8 +18,8 @@ public class HistogramErrorHandler implements ErrorHandler, ErrorMetrics.Aware {
private ExceptionHistoMetrics exceptionHistoMetrics;
@Override
public ErrorDetail handleError(Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
exceptionHistoMetrics.update(t, durationInNanos);
public ErrorDetail handleError(String name, Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
exceptionHistoMetrics.update(name, durationInNanos);
return detail;
}

View File

@@ -8,7 +8,7 @@ import io.nosqlbench.nb.annotations.Service;
public class IgnoreErrorHandler implements ErrorHandler {
@Override
public ErrorDetail handleError(Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
public ErrorDetail handleError(String name, Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
return detail;
}

View File

@@ -13,8 +13,8 @@ public class MeterErrorHandler implements ErrorHandler, ErrorMetrics.Aware {
private ExceptionMeterMetrics exceptionMeterMetrics;
@Override
public ErrorDetail handleError(Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
exceptionMeterMetrics.mark(t);
public ErrorDetail handleError(String name, Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
exceptionMeterMetrics.mark(name);
return detail;
}

View File

@@ -7,7 +7,7 @@ import io.nosqlbench.nb.annotations.Service;
@Service(value = ErrorHandler.class, selector = "retry")
public class RetryErrorHandler implements ErrorHandler {
@Override
public ErrorDetail handleError(Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
public ErrorDetail handleError(String name, Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
return detail.withRetryable();
}
}

View File

@@ -12,7 +12,7 @@ public class StopErrorHandler implements ErrorHandler {
private final static Logger logger = LogManager.getLogger(StopErrorHandler.class);
@Override
public ErrorDetail handleError(Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
public ErrorDetail handleError(String name, Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
throw new RuntimeException(t);
}
}

View File

@@ -15,8 +15,8 @@ public class TimerErrorHandler implements ErrorHandler, ErrorMetrics.Aware {
private ExceptionTimerMetrics exceptionTimerMetrics;
@Override
public ErrorDetail handleError(Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
exceptionTimerMetrics.update(t, durationInNanos);
public ErrorDetail handleError(String name, Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
exceptionTimerMetrics.update(name, durationInNanos);
return detail;
}

View File

@@ -11,7 +11,7 @@ public class WarnErrorHandler implements ErrorHandler {
private final static Logger logger = LogManager.getLogger("ERRORS");
@Override
public ErrorDetail handleError(Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
public ErrorDetail handleError(String name, Throwable t, long cycle, long durationInNanos, ErrorDetail detail) {
logger.warn("error with cycle " + cycle + " errmsg: " + t.getMessage());
return detail;
}