Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java - Add RedisException return to connection/command response handl… #788

Merged

Conversation

acarbonetto
Copy link
Contributor

Depends on #717.

Issue #, if available:

API layer for: #589

Description of changes:

In this PR, we're adding RedisException throwing when

  1. Creating a RedisClient and the connection response contains non-success.
  2. Sending a Redis Request and request response contains non-success.

Use Case:

CompletableFuture<RedisClient> createClientRequest = RedisClient.CreateClient(config); 

// throws ExecutionException with a RedisException on an unexpected failure
try (RedisClient client = createClientRequest.get()) 
{
    CompletableFuture<String> getRequest = client.get("key"); 
    String getValue = getRequest.get(); // throws ExecutionException with a RedisException on an unexpected failure
} catch (ExecutionException executionException) {
    if (executionException.getCause() instanceOf RedisException) {
         // try again
  }
}

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

…ing (#57)

* Add Redis exceptions and handling

Signed-off-by: Andrew Carbonetto <[email protected]>

---------

Signed-off-by: Andrew Carbonetto <[email protected]>
@acarbonetto acarbonetto requested a review from a team as a code owner January 12, 2024 23:31
@acarbonetto acarbonetto self-assigned this Jan 12, 2024
@acarbonetto acarbonetto added the java issues and fixes related to the java client label Jan 12, 2024
public CompletableFuture<Void> closeConnection() {
return CompletableFuture.runAsync(channel::close);
CompletableFuture<Void> completableFuture = new CompletableFuture<>();
channel
Copy link
Collaborator

@Yury-Fridlyand Yury-Fridlyand Jan 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can update this function to return Future<Void> to avoid such ugly conversion F -> CF

// TODO: marking resources as closed:
// https://github.com/orgs/Bit-Quill/projects/4/views/6?pane=issue&itemId=48063887
throw new RuntimeException(interruptedException);
} catch (InterruptedException e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry I didn't notice earlier - we use 4 spaces throughout the project:
https://github.com/aws/glide-for-redis/blob/2f901b0617fe1cce76de8449f9fc28ba30029c2d/.vscode/settings.json#L3
please fix your linter in a separate PR.

@@ -0,0 +1,8 @@
package glide.api.models.exceptions;

/** Error returned from Redis client: Redis is closing or unavailable to the client */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't invent new documentation, just use the existing comments used in python / TS. Same for all exception types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed under 37fee4a

}
throw new RuntimeException("Connection response expects an OK response");
// successful connection response has an "OK"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comment doesn't match the return type. what's intention behind the doc?

}

/** Close the connection and the corresponding channel. */
/** Close the connection to the channel. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment on nothing, repeating the next comment

@@ -162,28 +166,51 @@ private ConnectionRequestOuterClass.ReadFrom mapReadFromEnum(ReadFrom readFrom)
/** Check a response received from Glide. */
private Void checkGlideRsResponse(Response response) {
if (response.hasRequestError()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor:
considering we have 4 repeats of

   closeConnection();
   throw new ClosingException(<some message>);

maybe just invert the structure of the function:

private Void checkGlideRsResponse(Response response) {
  if (response.hasConstantResponse()) {
    return null;
  }
  var message;
  [...] // set message by the response type
  closeConnection();
  throw new ClosingException(message);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't trust that there is no error in the response.
The object could have both an error and a constant response. So I have to check for an error regardless.

Copy link
Contributor Author

@acarbonetto acarbonetto Jan 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consolidated the logic in 37fee4a

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't trust that there is no error in the response.

Why not?
I understand that Protobuf doesn't give an interface that promises that, but why can't you trust the core to set only one of the values?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best practices. I just don't know how core (and any interactive system) would behave in the future. And this provides an extra layer of protection for the user. I'm not sure the saving in processing time here are worth the potential costs of exposing a bug down the road.

@@ -84,7 +91,6 @@ public void ConnectionRequestProtobufGeneration_DefaultRedisClientConfiguration_
// verify
// no exception
assertNull(result.get());
verify(channel).connect(eq(expectedProtobufConnectionRequest));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does the test actually test without this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass without exception.

Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
Signed-off-by: Andrew Carbonetto <[email protected]>
@acarbonetto acarbonetto merged commit 11eb1fd into valkey-io:main Jan 16, 2024
3 checks passed
@acarbonetto acarbonetto deleted the java/integ_acarbo_api_redisExceptions branch January 16, 2024 02:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
java issues and fixes related to the java client
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants