Skip to content

Commit

Permalink
Merge branch 'puppetlabs:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
malikparvez authored Oct 11, 2023
2 parents faf1b5d + 4a9b599 commit 87692e6
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 24 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Starting with v2.0.0, all notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## v5.0.2 - 2023-09-29
* Correct a Digest call making this thread-safe and allowing for concurrent r10k deploys.
Thanks to @cmd-ntrf for fixing it and to @baurmatt for tracking it down in the first place.

## v5.0.1 - 2023-07-10
* Update README to reflect accurate Ruby requirement and `faraday` gem dependency
## v5.0.0 - 2023-05-07
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet_forge/lru_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class LruCache
# a convenience method for generating cache keys. Cache keys do not
# have to be SHA256 hashes, but they must be unique.
def self.new_key(*string_args)
Digest::SHA256.hexdigest(string_args.map(&:to_s).join(':'))
Digest(:SHA256).hexdigest(string_args.map(&:to_s).join(':'))
end

# @return [Integer] the maximum number of items to cache.
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet_forge/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module PuppetForge
VERSION = '5.0.1' # Library version
VERSION = '5.0.2' # Library version
end
66 changes: 44 additions & 22 deletions spec/unit/forge/lru_cache_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,26 @@
expect(cache.send(:lru)).to eq(['foo', 'baz'])
end

# The below test is non-deterministic but I'm not sure how to unit
# test thread-safety.
# it 'is thread-safe' do
# cache = PuppetForge::LruCache.new
# cache.put('foo', 'bar')
# cache.put('baz', 'qux')
# threads = []
# threads << Thread.new { 100.times { cache.get('foo') } }
# threads << Thread.new { 100.times { cache.get('baz') } }
# threads.each(&:join)
# expect(cache.send(:lru)).to eq(['baz', 'foo'])
# end
it 'is thread-safe for get calls' do
cache = PuppetForge::LruCache.new

# Populate the cache with initial values
cache.put('foo', 'bar')
cache.put('baz', 'qux')

# Create two threads for concurrent cache get operations
thread_one = Thread.new do
100.times { expect(cache.get('foo')).to eq('bar') }
end

thread_two = Thread.new do
100.times { expect(cache.get('baz')).to eq('qux') }
end

# Wait for both threads to complete
thread_one.join
thread_two.join
end
end

context '#put' do
Expand All @@ -102,16 +110,30 @@
expect(cache.send(:lru)).to eq(['quux', 'baz'])
end

# The below test is non-deterministic but I'm not sure how to unit
# test thread-safety.
# it 'is thread-safe' do
# cache = PuppetForge::LruCache.new
# threads = []
# threads << Thread.new { 100.times { cache.put('foo', 'bar') } }
# threads << Thread.new { 100.times { cache.put('baz', 'qux') } }
# threads.each(&:join)
# expect(cache.send(:lru)).to eq(['baz', 'foo'])
# end
it 'is thread-safe' do
cache = PuppetForge::LruCache.new

# Create two threads for concurrent cache operations
thread_one = Thread.new do
100.times { cache.put('foo', 'bar') }
end

thread_two = Thread.new do
100.times { cache.put('baz', 'qux') }
end

# Wait for both threads to complete
thread_one.join
thread_two.join

# At this point, we don't need to compare the LRU list,
# because the order may change due to concurrent puts.

# Instead, we simply expect the code to run without errors.
expect { thread_one.value }.not_to raise_error
expect { thread_two.value }.not_to raise_error
end

end

context '#clear' do
Expand Down

0 comments on commit 87692e6

Please sign in to comment.