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

Use before assignment of asyncDedicatedConnection in LettuceConnection #2984

Closed
oldium opened this issue Sep 5, 2024 · 7 comments
Closed
Assignees
Labels
type: bug A general bug

Comments

@oldium
Copy link

oldium commented Sep 5, 2024

I found issue while reading how Lettuce integration works in this method:

protected StatefulConnection<byte[], byte[]> doGetAsyncDedicatedConnection() {
StatefulConnection<byte[], byte[]> connection = getConnectionProvider().getConnection(StatefulConnection.class);
if (customizedDatabaseIndex()) {
potentiallySelectDatabase(this.dbIndex);
}
return connection;
}

The method creates a new connection, which is stored by the caller into a asyncDedicatedConnection attribute:

private StatefulConnection<byte[], byte[]> getOrCreateDedicatedConnection() {
if (this.asyncDedicatedConnection == null) {
this.asyncDedicatedConnection = doGetAsyncDedicatedConnection();
}
return this.asyncDedicatedConnection;
}

But it looks like the asyncDedicatedConnection is used before assignment in potentiallySelectDatabase() called by doGetAsyncDedicatedConnection():

private void potentiallySelectDatabase(int dbIndex) {
if (asyncDedicatedConnection instanceof StatefulRedisConnection<byte[], byte[]> statefulConnection) {
statefulConnection.sync().select(dbIndex);
}
}

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 5, 2024
@mp911de mp911de added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Sep 5, 2024
@mp911de
Copy link
Member

mp911de commented Sep 5, 2024

This is a bug, good catch. We need to apply the database selection clearly on the newly created connection. Do you want to submit a pull request?

@oldium
Copy link
Author

oldium commented Sep 5, 2024

Please do it if you have time :-)

oldium added a commit to oldium/spring-data-redis that referenced this issue Sep 8, 2024
When new connection is created in doGetAsyncDedicatedConnection(), it is
not yet assigned to asyncDedicatedConnection attribute, so it cannot be
used in potentiallySelectDatabase() call. Fix this by passing the
connection to the method.

Closes spring-projects#2984

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
@oldium
Copy link
Author

oldium commented Sep 8, 2024

Turns out the logic is broken here. select() refuses to use shared connection, so it executes the select command on a dedicated connection. This means that the potentiallySelectDatabase() call is superfluous in doGetAsyncDedicatedConnection, because the database change will be executed in select call anyway.

I am not able to tell the difference between connection.sync().select() (used in potentiallySelectDatabase method) and invokeStatus().just(..., CommandType.SELECT, ...) (used in select method), though.

oldium added a commit to oldium/spring-data-redis that referenced this issue Sep 8, 2024
When new connection is created in doGetAsyncDedicatedConnection(), it is
not yet assigned to asyncDedicatedConnection attribute, so it cannot be
used in potentiallySelectDatabase() call.

It seems that the select call is superfluous anyway here, because the
`select()` method call can be made only when the cached dedicated
connection is used (not a shared one) and the `select()` method always
selects the database immediately on the cached dedicated connection.

Therefore it should never be necessary to call select on newly created
dedicated connection, because it is either created by `select()` method
call or a default database is used.

Closes spring-projects#2984

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
@oldium
Copy link
Author

oldium commented Sep 8, 2024

Please check oldium@e47545a for possible fix. As I said, I am not sure whether the invokeStatus() (it uses RedisClusterAsyncCommands::dispatch, which is actually BaseRedisAsyncCommands::dispatch) is comparable/equivalent to connection.sync().select() call.

@mp911de mp911de self-assigned this Sep 11, 2024
mp911de added a commit that referenced this issue Sep 11, 2024
We now select the database on the dedicated connection. Previously, this call never happened on the dedicated connection and the only way a database could be selected is through the ConnectionFactory configuration.

Closes #2984
christophstrobl pushed a commit that referenced this issue Sep 12, 2024
We now select the database on the dedicated connection. Previously, this call never happened on the dedicated connection and the only way a database could be selected is through the ConnectionFactory configuration.

Closes: #2984
Original Pull Request: #2990
christophstrobl pushed a commit that referenced this issue Sep 12, 2024
We now select the database on the dedicated connection. Previously, this call never happened on the dedicated connection and the only way a database could be selected is through the ConnectionFactory configuration.

Closes: #2984
Original Pull Request: #2990
@christophstrobl christophstrobl added this to the 3.2.10 (2023.1.10) milestone Sep 12, 2024
@oldium
Copy link
Author

oldium commented Sep 12, 2024

@christophstrobl I do not think the fix is correct and the change to the test proves it. The SELECT Redis command is executed twice, first time in RedisCommands.select() call and second time in the BaseRedisAsyncCommands.dispatch(SELECT) call. Please see my former comments.

@christophstrobl
Copy link
Member

thanks for the heads up - true - working on it.

@mp911de
Copy link
Member

mp911de commented Sep 13, 2024

You're right, we're setting now the database index twice. We had initially a different understanding. By removing the database index customization check and db selection in doGetAsyncDedicatedConnection(…) we can address the issue.

christophstrobl added a commit that referenced this issue Sep 13, 2024
christophstrobl added a commit that referenced this issue Sep 13, 2024
christophstrobl added a commit that referenced this issue Sep 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants