Skip to content

Commit

Permalink
Refactoring for RequestRetryPolicies and classes in exceptions.errors…
Browse files Browse the repository at this point in the history
… package (#162)

Added TarantoolNoSuchProcedureException and refactored TarantoolErrors for parsing errors from MsgPack maps
  • Loading branch information
wey1and committed Feb 10, 2022
1 parent a9bfb28 commit 5ed7e3e
Show file tree
Hide file tree
Showing 27 changed files with 483 additions and 285 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,13 @@ TarantoolClient<TarantoolTuple, TarantoolResult<TarantoolTuple>> retrying(
TarantoolClient<TarantoolTuple, TarantoolResult<TarantoolTuple>> client, int retries, long delay) {
return TarantoolClientFactory.configureClient(client)
.withRetryingByNumberOfAttempts(
retries,
e -> e.getMessage().contains("Unsuccessful attempt"),
policy -> policy.withDelay(delay))
retries,
// you can use default predicates from TarantoolRequestRetryPolicies for checking errors
TarantoolRequestRetryPolicies.retryNetworkErrors()
// also you can use your own predicates and combine them with each other or with defaults
.or(e -> e.getMessage().contains("Unsuccessful attempt"))
.or(TarantoolRequestRetryPolicies.retryTarantoolNoSuchProcedureErrors()),
policy -> policy.withDelay(delay))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import io.tarantool.driver.api.retry.TarantoolRequestRetryPolicies;
import io.tarantool.driver.api.tuple.TarantoolTuple;

import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

/**
Expand Down Expand Up @@ -55,7 +55,7 @@ public interface TarantoolClientConfigurator<SELF extends TarantoolClientConfigu
*/
SELF withRetryingByNumberOfAttempts(
int numberOfAttempts, UnaryOperator<TarantoolRequestRetryPolicies
.AttemptsBoundRetryPolicyFactory.Builder<Function<Throwable, Boolean>>> policy);
.AttemptsBoundRetryPolicyFactory.Builder<Predicate<Throwable>>> policy);

/**
* Configure the attempts bound request retry policy.
Expand All @@ -67,7 +67,7 @@ SELF withRetryingByNumberOfAttempts(
* @param <T> callback type for exceptions check
* @return this instance of builder {@link TarantoolClientConfigurator}
*/
<T extends Function<Throwable, Boolean>> SELF withRetryingByNumberOfAttempts(
<T extends Predicate<Throwable>> SELF withRetryingByNumberOfAttempts(
int numberOfAttempts, T exceptionsCheck,
UnaryOperator<TarantoolRequestRetryPolicies.AttemptsBoundRetryPolicyFactory.Builder<T>> policy);

Expand All @@ -81,7 +81,7 @@ <T extends Function<Throwable, Boolean>> SELF withRetryingByNumberOfAttempts(
*/
SELF withRetryingIndefinitely(
UnaryOperator<TarantoolRequestRetryPolicies.InfiniteRetryPolicyFactory.Builder
<Function<Throwable, Boolean>>> policy);
<Predicate<Throwable>>> policy);

/**
* Configure the infinite request retry policy.
Expand All @@ -92,7 +92,7 @@ SELF withRetryingIndefinitely(
* @param <T> callback type for exceptions check
* @return this instance of builder {@link TarantoolClientConfigurator}
*/
<T extends Function<Throwable, Boolean>> SELF withRetryingIndefinitely(
<T extends Predicate<Throwable>> SELF withRetryingIndefinitely(
T callback,
UnaryOperator<TarantoolRequestRetryPolicies.InfiniteRetryPolicyFactory.Builder<T>> policy);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import java.util.function.Supplier;

/**
* Request retry policy contains an algorithm of deciding whether an exception is retriable and settings for
* Request retry policy contains an algorithm of deciding whether an exception is retryable and settings for
* limiting the retry attempts
*
* @author Alexey Kuzin
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ private TarantoolConnectionManager connectionManager() {

@Override
public boolean establishLackingConnections() {
return connectionManager.establishLackingConnections();
return connectionManager().establishLackingConnections();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import io.tarantool.driver.api.retry.TarantoolRequestRetryPolicies;
import io.tarantool.driver.api.tuple.TarantoolTuple;

import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

import static io.tarantool.driver.api.retry.TarantoolRequestRetryPolicies.retryNetworkErrors;
Expand Down Expand Up @@ -54,12 +54,12 @@ public SELF withRetryingByNumberOfAttempts(int numberOfAttempts) {
@Override
public SELF withRetryingByNumberOfAttempts(
int numberOfAttempts, UnaryOperator<TarantoolRequestRetryPolicies
.AttemptsBoundRetryPolicyFactory.Builder<Function<Throwable, Boolean>>> policy) {
.AttemptsBoundRetryPolicyFactory.Builder<Predicate<Throwable>>> policy) {
return withRetryingByNumberOfAttempts(numberOfAttempts, retryNetworkErrors(), policy);
}

@Override
public <T extends Function<Throwable, Boolean>> SELF withRetryingByNumberOfAttempts(
public <T extends Predicate<Throwable>> SELF withRetryingByNumberOfAttempts(
int numberOfAttempts, T exceptionsCheck,
UnaryOperator<TarantoolRequestRetryPolicies.AttemptsBoundRetryPolicyFactory.Builder<T>> policy) {
return withRetrying(policy.apply(TarantoolRequestRetryPolicies.AttemptsBoundRetryPolicyFactory
Expand All @@ -68,12 +68,12 @@ public <T extends Function<Throwable, Boolean>> SELF withRetryingByNumberOfAttem

@Override
public SELF withRetryingIndefinitely(UnaryOperator<TarantoolRequestRetryPolicies
.InfiniteRetryPolicyFactory.Builder<Function<Throwable, Boolean>>> policy) {
.InfiniteRetryPolicyFactory.Builder<Predicate<Throwable>>> policy) {
return withRetryingIndefinitely(retryNetworkErrors(), policy);
}

@Override
public <T extends Function<Throwable, Boolean>> SELF withRetryingIndefinitely(
public <T extends Predicate<Throwable>> SELF withRetryingIndefinitely(
T callback, UnaryOperator<TarantoolRequestRetryPolicies.InfiniteRetryPolicyFactory.Builder<T>> policy) {
return withRetrying(policy.apply(TarantoolRequestRetryPolicies.InfiniteRetryPolicyFactory.builder(callback))
.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public CompletableFuture<TarantoolConnection> singleConnection(InetSocketAddress
timeoutScheduler.schedule(() -> {
if (!connectionFuture.isDone()) {
connectionFuture.completeExceptionally(new TimeoutException(
String.format("Failed to to the Tarantool server at %s within %d ms",
String.format("Failed to connect to the Tarantool server at %s within %d ms",
serverAddress, config.getConnectTimeout())));
}
}, config.getConnectTimeout(), TimeUnit.MILLISECONDS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ private Map<String, TarantoolIndexMetadata> parseIndexes(Map<String, TarantoolFi
.map(parts -> {
if (!parts.isMapValue()) {
throw new TarantoolClientException(
"Unsupported index metadata format: index part metadata is not a map");
"Unsupported index metadata format: index part metadata is not a map");
}

Map<Value, Value> partsMap = parts.asMapValue().map();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.tarantool.driver.exceptions;

/**
* Corresponds to an exception that occurs when the procedure has not (yet) been defined in the Tarantool instance.
* <p></p>
* For example: this exception can be raised when a Cartridge role is not up yet or is being reloaded at the moment.
* This can happen when the tarantool 'router' node is restarted or hot-reloaded but the cluster is under
* load at the moment. If CRUD module is used in the cluster then 'cartridge.roles.crud-router' may
* have not been initialized yet and all requests to CRUD will fail with this exception.
*
* You can use this exception when you are sure that it's worth trying a few more times until the role is up.
*
* @author Oleg Kuznetsov
*/
public class TarantoolNoSuchProcedureException extends TarantoolException {
public TarantoolNoSuchProcedureException(String errorMessage) {
super(errorMessage);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.tarantool.driver.exceptions.errors;

import org.msgpack.value.StringValue;
import org.msgpack.value.ValueFactory;

/**
* Errors keys for error message in box error
*
* @author Oleg Kuznetsov
*/
enum BoxErrorKey implements ErrorKey {
CODE("code", ValueFactory.newString("code")),
BASE_TYPE("base_type", ValueFactory.newString("base_type")),
TYPE("type", ValueFactory.newString("type")),
MESSAGE("message", ValueFactory.newString("message")),
TRACE("trace", ValueFactory.newString("trace"));

private final String key;
private final StringValue msgPackKey;

BoxErrorKey(String key, StringValue msgPackKey) {
this.key = key;
this.msgPackKey = msgPackKey;
}

@Override
public String getKey() {
return key;
}

@Override
public StringValue getMsgPackKey() {
return msgPackKey;
}
}
20 changes: 20 additions & 0 deletions src/main/java/io/tarantool/driver/exceptions/errors/ErrorCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.tarantool.driver.exceptions.errors;

/**
* Error codes used to classify errors
* <a href="https://github.com/tarantool/tarantool/blob/master/src/box/errcode.h">Tarantool error codes</a>
*
* @author Oleg Kuznetsov
*/
enum ErrorCode {
NO_SUCH_PROCEDURE(33L), NO_CONNECTION(77L), TIMEOUT(78L);
private final Long code;

ErrorCode(Long code) {
this.code = code;
}

public Long getCode() {
return code;
}
}
14 changes: 14 additions & 0 deletions src/main/java/io/tarantool/driver/exceptions/errors/ErrorKey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.tarantool.driver.exceptions.errors;

import org.msgpack.value.StringValue;

/**
* Representations for error key
*
* @author Oleg Kuznetsov
*/
interface ErrorKey {
String getKey();

StringValue getMsgPackKey();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.tarantool.driver.exceptions.errors;

import org.msgpack.value.StringValue;
import org.msgpack.value.Value;

import java.util.Map;

/**
* This class can create error message by keys from msgPack error response
*
* @author Oleg Kuznetsov
*/
class ErrorMessageBuilder {

private final StringBuilder stringBuilder;
private final Map<Value, Value> values;
private final ErrorKey[] keys;

ErrorMessageBuilder(String startsWith, ErrorKey[] keys, Map<Value, Value> values) {
this.stringBuilder = new StringBuilder(startsWith);
this.values = values;
this.keys = keys;
}

String build() {
for (ErrorKey key : keys) {
final StringValue stringValue = key.getMsgPackKey();
final String s = values.containsKey(stringValue) ? values.get(stringValue).toString() : null;
if (s != null && s.length() != 0) {
stringBuilder.append("\n").append(key.getKey().toLowerCase()).append(": ").append(s);
}
}

return stringBuilder.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.tarantool.driver.exceptions.errors;

import org.msgpack.value.StringValue;
import org.msgpack.value.ValueFactory;

/**
* Errors keys for error message from tarantool/errors library
*
* @author Oleg Kuznetsov
*/
enum ErrorsErrorKey implements ErrorKey {
LINE("line", ValueFactory.newString("line")),
CLASS_NAME("class_name", ValueFactory.newString("class_name")),
ERR("err", ValueFactory.newString("err")),
FILE("file", ValueFactory.newString("file")),
ERROR_MESSAGE("str", ValueFactory.newString("str")),
STACKTRACE("stack", ValueFactory.newString("stack"));

private final String key;
private final StringValue msgPackKey;

ErrorsErrorKey(String key, StringValue msgPackKey) {
this.key = key;
this.msgPackKey = msgPackKey;
}

@Override
public String getKey() {
return key;
}

@Override
public StringValue getMsgPackKey() {
return msgPackKey;
}
}
Loading

0 comments on commit 5ed7e3e

Please sign in to comment.