Skip to content

Commit

Permalink
GS version for fcall and fcallReadOnly (#1639)
Browse files Browse the repository at this point in the history
* GS version for fcall and fcallReadOnly. Also changed integTests like *function*commands*binary* to use fcall/fcall_RO binary version
  • Loading branch information
talxsha authored Jul 2, 2024
1 parent e2aafd7 commit cc26eb0
Show file tree
Hide file tree
Showing 10 changed files with 770 additions and 12 deletions.
22 changes: 22 additions & 0 deletions java/client/src/main/java/glide/api/BaseClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -3195,6 +3195,17 @@ public CompletableFuture<Object> fcall(
return commandManager.submitNewCommand(FCall, args, this::handleObjectOrNullResponse);
}

@Override
public CompletableFuture<Object> fcall(
@NonNull GlideString function,
@NonNull GlideString[] keys,
@NonNull GlideString[] arguments) {
GlideString[] args =
concatenateArrays(
new GlideString[] {function, gs(Long.toString(keys.length))}, keys, arguments);
return commandManager.submitNewCommand(FCall, args, this::handleObjectOrNullResponse);
}

@Override
public CompletableFuture<Object> fcallReadOnly(
@NonNull String function, @NonNull String[] keys, @NonNull String[] arguments) {
Expand All @@ -3203,6 +3214,17 @@ public CompletableFuture<Object> fcallReadOnly(
return commandManager.submitNewCommand(FCallReadOnly, args, this::handleObjectOrNullResponse);
}

@Override
public CompletableFuture<Object> fcallReadOnly(
@NonNull GlideString function,
@NonNull GlideString[] keys,
@NonNull GlideString[] arguments) {
GlideString[] args =
concatenateArrays(
new GlideString[] {function, gs(Long.toString(keys.length))}, keys, arguments);
return commandManager.submitNewCommand(FCallReadOnly, args, this::handleObjectOrNullResponse);
}

@Override
public CompletableFuture<Boolean> copy(
@NonNull String source, @NonNull String destination, boolean replace) {
Expand Down
10 changes: 10 additions & 0 deletions java/client/src/main/java/glide/api/RedisClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,21 @@ public CompletableFuture<Object> fcall(@NonNull String function) {
return fcall(function, new String[0], new String[0]);
}

@Override
public CompletableFuture<Object> fcall(@NonNull GlideString function) {
return fcall(function, new GlideString[0], new GlideString[0]);
}

@Override
public CompletableFuture<Object> fcallReadOnly(@NonNull String function) {
return fcallReadOnly(function, new String[0], new String[0]);
}

@Override
public CompletableFuture<Object> fcallReadOnly(@NonNull GlideString function) {
return fcallReadOnly(function, new GlideString[0], new GlideString[0]);
}

@Override
public CompletableFuture<Boolean> copy(
@NonNull String source, @NonNull String destination, long destinationDB) {
Expand Down
68 changes: 68 additions & 0 deletions java/client/src/main/java/glide/api/RedisClusterClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -717,18 +717,37 @@ public CompletableFuture<Object> fcall(@NonNull String function) {
return fcall(function, new String[0]);
}

@Override
public CompletableFuture<Object> fcall(@NonNull GlideString function) {
return fcall(function, new GlideString[0]);
}

@Override
public CompletableFuture<ClusterValue<Object>> fcall(
@NonNull String function, @NonNull Route route) {
return fcall(function, new String[0], route);
}

@Override
public CompletableFuture<ClusterValue<Object>> fcall(
@NonNull GlideString function, @NonNull Route route) {
return fcall(function, new GlideString[0], route);
}

@Override
public CompletableFuture<Object> fcall(@NonNull String function, @NonNull String[] arguments) {
String[] args = concatenateArrays(new String[] {function, "0"}, arguments); // 0 - key count
return commandManager.submitNewCommand(FCall, args, this::handleObjectOrNullResponse);
}

@Override
public CompletableFuture<Object> fcall(
@NonNull GlideString function, @NonNull GlideString[] arguments) {
GlideString[] args =
concatenateArrays(new GlideString[] {function, gs("0")}, arguments); // 0 - key count
return commandManager.submitNewCommand(FCall, args, this::handleObjectOrNullResponse);
}

@Override
public CompletableFuture<ClusterValue<Object>> fcall(
@NonNull String function, @NonNull String[] arguments, @NonNull Route route) {
Expand All @@ -743,24 +762,58 @@ public CompletableFuture<ClusterValue<Object>> fcall(
: ClusterValue.ofMultiValue(handleMapResponse(response)));
}

@Override
public CompletableFuture<ClusterValue<Object>> fcall(
@NonNull GlideString function, @NonNull GlideString[] arguments, @NonNull Route route) {
GlideString[] args =
concatenateArrays(new GlideString[] {function, gs("0")}, arguments); // 0 - key count
return commandManager.submitNewCommand(
FCall,
args,
route,
response ->
route instanceof SingleNodeRoute
? ClusterValue.ofSingleValue(handleObjectOrNullResponse(response))
: ClusterValue.ofMultiValue(handleMapResponse(response)));
}

@Override
public CompletableFuture<Object> fcallReadOnly(@NonNull String function) {
return fcallReadOnly(function, new String[0]);
}

@Override
public CompletableFuture<Object> fcallReadOnly(@NonNull GlideString function) {
return fcallReadOnly(function, new GlideString[0]);
}

@Override
public CompletableFuture<ClusterValue<Object>> fcallReadOnly(
@NonNull String function, @NonNull Route route) {
return fcallReadOnly(function, new String[0], route);
}

@Override
public CompletableFuture<ClusterValue<Object>> fcallReadOnly(
@NonNull GlideString function, @NonNull Route route) {
return fcallReadOnly(function, new GlideString[0], route);
}

@Override
public CompletableFuture<Object> fcallReadOnly(
@NonNull String function, @NonNull String[] arguments) {
String[] args = concatenateArrays(new String[] {function, "0"}, arguments); // 0 - key count
return commandManager.submitNewCommand(FCallReadOnly, args, this::handleObjectOrNullResponse);
}

@Override
public CompletableFuture<Object> fcallReadOnly(
@NonNull GlideString function, @NonNull GlideString[] arguments) {
GlideString[] args =
concatenateArrays(new GlideString[] {function, gs("0")}, arguments); // 0 - key count
return commandManager.submitNewCommand(FCallReadOnly, args, this::handleObjectOrNullResponse);
}

@Override
public CompletableFuture<ClusterValue<Object>> fcallReadOnly(
@NonNull String function, @NonNull String[] arguments, @NonNull Route route) {
Expand All @@ -775,6 +828,21 @@ public CompletableFuture<ClusterValue<Object>> fcallReadOnly(
: ClusterValue.ofMultiValue(handleMapResponse(response)));
}

@Override
public CompletableFuture<ClusterValue<Object>> fcallReadOnly(
@NonNull GlideString function, @NonNull GlideString[] arguments, @NonNull Route route) {
GlideString[] args =
concatenateArrays(new GlideString[] {function, gs("0")}, arguments); // 0 - key count
return commandManager.submitNewCommand(
FCallReadOnly,
args,
route,
response ->
route instanceof SingleNodeRoute
? ClusterValue.ofSingleValue(handleObjectOrNullResponse(response))
: ClusterValue.ofMultiValue(handleMapResponse(response)));
}

@Override
public CompletableFuture<String> functionKill() {
return commandManager.submitNewCommand(FunctionKill, new String[0], this::handleStringResponse);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/** Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 */
package glide.api.commands;

import glide.api.models.GlideString;
import glide.api.models.configuration.ReadFrom;
import java.util.concurrent.CompletableFuture;

Expand Down Expand Up @@ -42,6 +43,36 @@ public interface ScriptingAndFunctionsBaseCommands {
*/
CompletableFuture<Object> fcall(String function, String[] keys, String[] arguments);

/**
* Invokes a previously loaded function.<br>
* This command is routed to primary nodes only.<br>
* To route to a replica please refer to {@link #fcallReadOnly}.
*
* @apiNote When in cluster mode
* <ul>
* <li>all <code>keys</code> must map to the same hash slot.
* <li>if no <code>keys</code> are given, command will be routed to a random primary node.
* </ul>
*
* @since Redis 7.0 and above.
* @see <a href="https://redis.io/docs/latest/commands/fcall/">redis.io</a> for details.
* @param function The function name.
* @param keys An <code>array</code> of keys accessed by the function. To ensure the correct
* execution of functions, both in standalone and clustered deployments, all names of keys
* that a function accesses must be explicitly provided as <code>keys</code>.
* @param arguments An <code>array</code> of <code>function</code> arguments. <code>arguments
* </code> should not represent names of keys.
* @return The invoked function's return value.
* @example
* <pre>{@code
* GlideString[] args = new GlideString[] { gs("Answer"), gs("to"), gs("the"), gs("Ultimate"), gs("Question"), gs("of"), gs("Life,"), gs("the"), gs("Universe,"), gs("and"), gs("Everything")};
* Object response = client.fcall(gs("Deep_Thought"), new GlideString[0], args).get();
* assert response == 42L;
* }</pre>
*/
CompletableFuture<Object> fcall(
GlideString function, GlideString[] keys, GlideString[] arguments);

/**
* Invokes a previously loaded read-only function.<br>
* This command is routed depending on the client's {@link ReadFrom} strategy.
Expand Down Expand Up @@ -69,4 +100,33 @@ public interface ScriptingAndFunctionsBaseCommands {
* }</pre>
*/
CompletableFuture<Object> fcallReadOnly(String function, String[] keys, String[] arguments);

/**
* Invokes a previously loaded read-only function.<br>
* This command is routed depending on the client's {@link ReadFrom} strategy.
*
* @apiNote When in cluster mode
* <ul>
* <li>all <code>keys</code> must map to the same hash slot.
* <li>if no <code>keys</code> are given, command will be routed to a random node.
* </ul>
*
* @since Redis 7.0 and above.
* @see <a href="https://redis.io/docs/latest/commands/fcall_ro/">redis.io</a> for details.
* @param function The function name.
* @param keys An <code>array</code> of keys accessed by the function. To ensure the correct
* execution of functions, both in standalone and clustered deployments, all names of keys
* that a function accesses must be explicitly provided as <code>keys</code>.
* @param arguments An <code>array</code> of <code>function</code> arguments. <code>arguments
* </code> should not represent names of keys.
* @return The invoked function's return value.
* @example
* <pre>{@code
* GlideString[] args = new GlideString[] { gs("Answer"), gs("to"), gs("the"), gs("Ultimate"), gs("Question"), gs("of"), gs("Life,"), gs("the"), gs("Universe,"), gs("and"), gs("Everything")};
* Object response = client.fcallReadOnly(gs("Deep_Thought"), new GlideString[0], args).get();
* assert response == 42L;
* }</pre>
*/
CompletableFuture<Object> fcallReadOnly(
GlideString function, GlideString[] keys, GlideString[] arguments);
}
Loading

0 comments on commit cc26eb0

Please sign in to comment.