Skip to content

Fix race condition in AbstractRedisReactiveCommands.getScheduler #3271

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

Closed
wants to merge 1 commit into from

Conversation

ori0o0p
Copy link
Contributor

@ori0o0p ori0o0p commented Apr 24, 2025

This pull request addresses the thread-safety issue in the lazy initialization logic of AbstractRedisReactiveCommands.getScheduler().

Problem:

As described in issue #3272, the previous implementation, despite using a volatile field for scheduler, suffered from a race condition. Multiple threads could pass the initial null check concurrently before the field was assigned, leading to the initialization logic potentially running multiple times. This is because the "check-then-act" sequence was not atomic.

Solution:

This change implements the full Double-Checked Locking (DCL) pattern by adding a synchronized(this) block. This block protects the second null check and the assignment to the scheduler field, ensuring that the initialization happens exactly once and is safely published to all threads. The existing volatile keyword is essential for the correctness of DCL.

This approach guarantees thread-safe lazy initialization and prevents potential resource issues caused by redundant initialization attempts.

Related Issue: Closes #3272


Make sure that:

  • You have read the contribution guidelines.
  • You have created a feature request first to discuss your contribution intent. Please reference the feature request ticket number in the pull request.
  • You applied code formatting rules using the mvn formatter:format target. Don’t submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.

Applied Double-Checked Locking pattern with a synchronized block to
prevent race conditions during concurrent access to the scheduler field
in AbstractRedisReactiveCommands. The field was already volatile, but
the check-then-act sequence was not atomic.
@tishun tishun requested a review from Copilot April 25, 2025 07:47
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes a race condition in the lazy initialization logic of scheduler in AbstractRedisReactiveCommands by implementing the full double-checked locking pattern.

  • Implements synchronized block with a second null-check to ensure thread-safe lazy initialization.
  • Eliminates redundant local variables and streamlines the scheduler assignment logic.
Comments suppressed due to low confidence (2)

src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java:136

  • Consider adding concurrent unit tests to verify that the updated double-checked locking logic reliably prevents multiple scheduler initializations under multi-threaded access.
EventExecutorGroup result = scheduler;

src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java:136

  • [nitpick] The local variable 'result' could be renamed to something more descriptive (e.g., 'computedScheduler') to improve readability.
EventExecutorGroup result = scheduler;

@tishun
Copy link
Collaborator

tishun commented May 7, 2025

Hey, @ori0o0p , could you rebase your change with the fix to the tests in #3273

@tishun tishun added the status: declined A suggestion or change that we dont feel we should currently apply label May 28, 2025
@tishun
Copy link
Collaborator

tishun commented May 28, 2025

See discussion in #3272

@tishun tishun closed this May 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we dont feel we should currently apply
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix Thread-safety race condition in AbstractRedisReactiveCommands.getScheduler()
2 participants