Fix race condition in Builder#build with thread-safe lazy initialization #2799
+112
−40
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a race condition in
Builder#buildthat causesNoMethodError: undefined method '[]' for nil:NilClasswhen multiple threads concurrently access uploader versions for the first time.Problem
The
Builderclass uses lazy initialization for version classes. Without synchronization, concurrent threads can observe a partially initialized@klasswhere the class is created butversion_optionsis not yet set:When
version_active?tries to accessversion_options[:if]on the partially initialized class, it fails:This manifests in multi-threaded environments (like Sidekiq workers) when multiple threads simultaneously access versions for the first time after a process starts.
Solution
Uses double-checked locking pattern with a Mutex:
@klassafter full initializationThis ensures other threads never see a partially initialized class.
Also updates
deep_dupto create a newMutexfor duplicated builders, preventing shared mutex state across inheritance.Test Plan
Related Issues
Related to issues involving race conditions or thread-safety in version building.