Skip to content

Commit

Permalink
Add references to arguments and result mappers to signatures
Browse files Browse the repository at this point in the history
There was a problem with the previous approach if we were going to call
a polymorphic remote function that will return results with different
schema depending on the argument. That is the case for calling the
tarantool/crud functions for example - the schema depends on the space
metadata. But if we supply a result mapper for each call, for each
result schema it will be different. So the hashcode of the result mapper
supplier is now included in the request signature, as well as the
hashcode of the arguments mapper supplier.

Here we assume that if we have identical mappers for two calls, their
suppliers must be also identical. Therefore we can have two possible
problems:
 - cash pollution if a mapper supplier for the same mapper is created
 for each call,
 - mapping errors if the supplier is polymorphic and the same supplier
 instance is used for calls with different result schema.
Both problems actually relate to a somehow bad written code, so they
does not look like showstoppers. The second problem also looks like a
rare one, but to avoid sudden user application crash in case of the
first one we need perhaps to define the maximum cache size and establish
eviction for the cash entries.
  • Loading branch information
akudiyar committed Oct 8, 2023
1 parent e2c4ff3 commit 1d82611
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ <T> CompletableFuture<T> call(
<T> CompletableFuture<TarantoolResult<T>> callForTupleResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Class<T> entityClass)
throws TarantoolClientException;

Expand All @@ -151,7 +151,7 @@ <T> CompletableFuture<TarantoolResult<T>> callForTupleResult(
<T> CompletableFuture<T> call(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<CallResultMapper<T, SingleValueCallResult<T>>> resultMapperSupplier)
throws TarantoolClientException;

Expand All @@ -170,7 +170,7 @@ <T> CompletableFuture<T> call(
<T> CompletableFuture<T> callForSingleResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Class<T> resultClass)
throws TarantoolClientException;

Expand All @@ -189,7 +189,7 @@ <T> CompletableFuture<T> callForSingleResult(
<T> CompletableFuture<T> callForSingleResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
ValueConverter<Value, T> valueConverter)
throws TarantoolClientException;

Expand All @@ -208,7 +208,7 @@ <T> CompletableFuture<T> callForSingleResult(
<T> CompletableFuture<T> callForSingleResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<CallResultMapper<T, SingleValueCallResult<T>>> resultMapperSupplier)
throws TarantoolClientException;

Expand Down Expand Up @@ -324,7 +324,7 @@ <T> CompletableFuture<T> callForSingleResult(
<T, R extends List<T>> CompletableFuture<R> callForMultiResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<R> resultContainerSupplier,
Class<T> resultClass)
throws TarantoolClientException;
Expand All @@ -345,7 +345,7 @@ <T, R extends List<T>> CompletableFuture<R> callForMultiResult(
<T, R extends List<T>> CompletableFuture<R> callForMultiResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<R> resultContainerSupplier,
ValueConverter<Value, T> valueConverter)
throws TarantoolClientException;
Expand All @@ -365,7 +365,7 @@ <T, R extends List<T>> CompletableFuture<R> callForMultiResult(
<T, R extends List<T>> CompletableFuture<R> callForMultiResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<CallResultMapper<R, MultiValueCallResult<T, R>>> resultMapperSupplier)
throws TarantoolClientException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public interface TarantoolEvalOperations {
* @return some result
* @throws TarantoolClientException if the client is not connected
*/
CompletableFuture<List<?>> eval(String expression, Supplier<MessagePackValueMapper> resultMapperSupplier)
CompletableFuture<List<?>> eval(String expression, Supplier<? extends MessagePackValueMapper> resultMapperSupplier)
throws TarantoolClientException;

/**
Expand All @@ -63,7 +63,7 @@ CompletableFuture<List<?>> eval(String expression, Supplier<MessagePackValueMapp
* @throws TarantoolClientException if the client is not connected
*/
CompletableFuture<List<?>> eval(
String expression, Collection<?> arguments, Supplier<MessagePackValueMapper> resultMapperSupplier)
String expression, Collection<?> arguments, Supplier<? extends MessagePackValueMapper> resultMapperSupplier)
throws TarantoolClientException;

/**
Expand All @@ -80,6 +80,6 @@ CompletableFuture<List<?>> eval(
CompletableFuture<List<?>> eval(
String expression,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<MessagePackValueMapper> resultMapperSupplier) throws TarantoolClientException;
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackValueMapper> resultMapperSupplier) throws TarantoolClientException;
}
68 changes: 38 additions & 30 deletions src/main/java/io/tarantool/driver/core/AbstractTarantoolClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -280,19 +280,22 @@ public <T> CompletableFuture<T> call(
public <T> CompletableFuture<TarantoolResult<T>> callForTupleResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Class<T> tupleClass)
throws TarantoolClientException {
TarantoolRequestSignature signature = TarantoolRequestSignature.create(functionName, arguments, tupleClass);
return callForSingleResult(functionName, arguments, signature, argumentsMapperSupplier,
() -> mapperFactoryFactory.getTarantoolResultMapper(config.getMessagePackMapper(), tupleClass));
Supplier<CallResultMapper<TarantoolResult<T>, SingleValueCallResult<TarantoolResult<T>>>>
resultMapperSupplier = () ->
mapperFactoryFactory.getTarantoolResultMapper(config.getMessagePackMapper(), tupleClass);
TarantoolRequestSignature signature = TarantoolRequestSignature.create(
functionName, arguments, tupleClass, argumentsMapperSupplier, resultMapperSupplier);
return callForSingleResult(functionName, arguments, signature, argumentsMapperSupplier, resultMapperSupplier);
}

@Override
public <T> CompletableFuture<T> call(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<CallResultMapper<T, SingleValueCallResult<T>>> resultMapperSupplier)
throws TarantoolClientException {
return callForSingleResult(functionName, arguments, argumentsMapperSupplier, resultMapperSupplier);
Expand Down Expand Up @@ -347,34 +350,35 @@ public <S> CompletableFuture<S> callForSingleResult(
public <S> CompletableFuture<S> callForSingleResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Class<S> resultClass)
throws TarantoolClientException {
TarantoolRequestSignature signature = TarantoolRequestSignature.create(functionName, arguments, resultClass);
return callForSingleResult(
functionName, arguments, signature, argumentsMapperSupplier,
() -> mapperFactoryFactory.getDefaultSingleValueMapper(config.getMessagePackMapper(), resultClass));
Supplier<CallResultMapper<S, SingleValueCallResult<S>>> resultMapperSupplier = () ->
mapperFactoryFactory.getDefaultSingleValueMapper(config.getMessagePackMapper(), resultClass);
TarantoolRequestSignature signature = TarantoolRequestSignature.create(
functionName, arguments, resultClass, argumentsMapperSupplier, resultMapperSupplier);
return callForSingleResult(functionName, arguments, signature, argumentsMapperSupplier, resultMapperSupplier);
}

@Override
public <S> CompletableFuture<S> callForSingleResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
ValueConverter<Value, S> valueConverter)
throws TarantoolClientException {
Supplier<CallResultMapper<S, SingleValueCallResult<S>>> resultMapperSupplier = () ->
mapperFactoryFactory.getSingleValueResultMapper(valueConverter);
TarantoolRequestSignature signature = TarantoolRequestSignature.create(
functionName, arguments, valueConverter.getClass());
functionName, arguments, valueConverter.getClass(), argumentsMapperSupplier, resultMapperSupplier);
return callForSingleResult(functionName, arguments, signature, argumentsMapperSupplier, resultMapperSupplier);
}

private <S> CompletableFuture<S> callForSingleResult(
String functionName,
Collection<?> arguments,
TarantoolRequestSignature signature,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<CallResultMapper<S, SingleValueCallResult<S>>> resultMapperSupplier)
throws TarantoolClientException {
return makeRequestForSingleResult(
Expand All @@ -386,7 +390,7 @@ private <S> CompletableFuture<S> callForSingleResult(
public <S> CompletableFuture<S> callForSingleResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<CallResultMapper<S, SingleValueCallResult<S>>> resultMapperSupplier)
throws TarantoolClientException {
return makeRequestForSingleResult(
Expand Down Expand Up @@ -454,35 +458,37 @@ public <T, R extends List<T>> CompletableFuture<R> callForMultiResult(
public <T, R extends List<T>> CompletableFuture<R> callForMultiResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<R> resultContainerSupplier,
Class<T> resultClass)
throws TarantoolClientException {
TarantoolRequestSignature signature = TarantoolRequestSignature.create(functionName, arguments, resultClass);
return callForMultiResult(functionName, arguments, signature, argumentsMapperSupplier,
() -> mapperFactoryFactory.getDefaultMultiValueMapper(config.getMessagePackMapper(), resultClass));
Supplier<CallResultMapper<R, MultiValueCallResult<T, R>>> resultMapperSupplier = () ->
mapperFactoryFactory.getDefaultMultiValueMapper(config.getMessagePackMapper(), resultClass);
TarantoolRequestSignature signature = TarantoolRequestSignature.create(
functionName, arguments, resultClass, argumentsMapperSupplier, resultMapperSupplier);
return callForMultiResult(functionName, arguments, signature, argumentsMapperSupplier, resultMapperSupplier);
}

@Override
public <T, R extends List<T>> CompletableFuture<R> callForMultiResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<R> resultContainerSupplier,
ValueConverter<Value, T> valueConverter)
throws TarantoolClientException {
Supplier<CallResultMapper<R, MultiValueCallResult<T, R>>> resultMapperSupplier = () ->
mapperFactoryFactory.getMultiValueResultMapper(resultContainerSupplier, valueConverter);
TarantoolRequestSignature signature = TarantoolRequestSignature.create(
functionName, arguments, valueConverter.getClass());
functionName, arguments, valueConverter.getClass(), argumentsMapperSupplier, resultMapperSupplier);
return callForMultiResult(functionName, arguments, signature, argumentsMapperSupplier, resultMapperSupplier);
}

private <T, R extends List<T>> CompletableFuture<R> callForMultiResult(
String functionName,
Collection<?> arguments,
TarantoolRequestSignature signature,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<CallResultMapper<R, MultiValueCallResult<T, R>>> resultMapperSupplier)
throws TarantoolClientException {
return makeRequestForMultiResult(
Expand All @@ -494,7 +500,7 @@ private <T, R extends List<T>> CompletableFuture<R> callForMultiResult(
public <T, R extends List<T>> CompletableFuture<R> callForMultiResult(
String functionName,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<CallResultMapper<R, MultiValueCallResult<T, R>>> resultMapperSupplier)
throws TarantoolClientException {
return makeRequestForMultiResult(functionName, arguments, null, argumentsMapperSupplier, resultMapperSupplier)
Expand All @@ -505,7 +511,7 @@ private <T> CompletableFuture<CallResult<T>> makeRequestForSingleResult(
String functionName,
Collection<?> arguments,
TarantoolRequestSignature requestSignature,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<CallResultMapper<T, SingleValueCallResult<T>>> resultMapperSupplier) {
return makeRequest(functionName, arguments, requestSignature, argumentsMapperSupplier, resultMapperSupplier);
}
Expand All @@ -514,7 +520,7 @@ private <T, R extends List<T>> CompletableFuture<CallResult<R>> makeRequestForMu
String functionName,
Collection<?> arguments,
TarantoolRequestSignature requestSignature,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<CallResultMapper<R, MultiValueCallResult<T, R>>> resultMapperSupplier) {
return makeRequest(functionName, arguments, requestSignature, argumentsMapperSupplier, resultMapperSupplier);
}
Expand All @@ -523,7 +529,7 @@ private <S> CompletableFuture<S> makeRequest(
String functionName,
Collection<?> arguments,
TarantoolRequestSignature requestSignature,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackValueMapper> resultMapperSupplier)
throws TarantoolClientException {
try {
Expand Down Expand Up @@ -562,14 +568,15 @@ public CompletableFuture<List<?>> eval(String expression, Collection<?> argument
}

@Override
public CompletableFuture<List<?>> eval(String expression, Supplier<MessagePackValueMapper> resultMapperSupplier)
public CompletableFuture<List<?>> eval(
String expression, Supplier<? extends MessagePackValueMapper> resultMapperSupplier)
throws TarantoolClientException {
return eval(expression, Collections.emptyList(), resultMapperSupplier);
}

@Override
public CompletableFuture<List<?>> eval(
String expression, Collection<?> arguments, Supplier<MessagePackValueMapper> resultMapperSupplier)
String expression, Collection<?> arguments, Supplier<? extends MessagePackValueMapper> resultMapperSupplier)
throws TarantoolClientException {
return eval(expression, arguments, config::getMessagePackMapper, resultMapperSupplier);
}
Expand All @@ -578,10 +585,11 @@ public CompletableFuture<List<?>> eval(
public CompletableFuture<List<?>> eval(
String expression,
Collection<?> arguments,
Supplier<MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<MessagePackValueMapper> resultMapperSupplier) throws TarantoolClientException {
Supplier<? extends MessagePackObjectMapper> argumentsMapperSupplier,
Supplier<? extends MessagePackValueMapper> resultMapperSupplier) throws TarantoolClientException {
try {
TarantoolRequestSignature signature = TarantoolRequestSignature.create(expression, arguments, List.class);
TarantoolRequestSignature signature = TarantoolRequestSignature.create(
expression, arguments, List.class, argumentsMapperSupplier, resultMapperSupplier);
MessagePackObjectMapper argumentsMapper = argumentsMapperCache.computeIfAbsent(
signature, s -> argumentsMapperSupplier.get());
MessagePackValueMapper resultMapper = resultMapperCache.computeIfAbsent(
Expand Down
Loading

0 comments on commit 1d82611

Please sign in to comment.