File tree Expand file tree Collapse file tree 4 files changed +57
-5
lines changed Expand file tree Collapse file tree 4 files changed +57
-5
lines changed Original file line number Diff line number Diff line change @@ -16,6 +16,7 @@ class Configuration
1616 def initialize
1717 @hooks = [ ]
1818 @providers = { }
19+ @provider_mutex = Mutex . new
1920 end
2021
2122 def provider ( domain : nil )
@@ -27,11 +28,13 @@ def provider(domain: nil)
2728 # 2. On the new provider, call `init`.
2829 # 3. Finally, set the internal provider to the new provider
2930 def set_provider ( provider , domain : nil )
30- @providers [ domain ] . shutdown if @providers [ domain ] . respond_to? ( :shutdown )
31-
32- provider . init if provider . respond_to? ( :init )
33-
34- @providers [ domain ] = provider
31+ @provider_mutex . synchronize do
32+ @providers [ domain ] . shutdown if @providers [ domain ] . respond_to? ( :shutdown )
33+ provider . init if provider . respond_to? ( :init )
34+ new_providers = @providers . dup
35+ new_providers [ domain ] = provider
36+ @providers = new_providers
37+ end
3538 end
3639 end
3740 end
Original file line number Diff line number Diff line change 3838 expect ( configuration . provider ( domain : "testing" ) ) . to be ( provider )
3939 end
4040 end
41+
42+ context "when the provider is set concurrently" do
43+ let ( :provider ) { OpenFeature ::SDK ::Provider ::InMemoryProvider . new }
44+ it "does not not call shutdown hooks multiple times if multithreaded" do
45+ providers = ( 0 ..2 ) . map { OpenFeature ::SDK ::Provider ::NoOpProvider . new }
46+ providers . each { |provider | expect ( provider ) . to receive ( :init ) }
47+ providers [ 0 , 2 ] . each { |provider | expect ( provider ) . to receive ( :shutdown ) }
48+ configuration . set_provider ( providers [ 0 ] )
49+
50+ allow ( providers [ 0 ] ) . to receive ( :shutdown ) . once { sleep 0.5 }
51+ background { configuration . set_provider ( providers [ 1 ] ) }
52+ background { configuration . set_provider ( providers [ 2 ] ) }
53+ yield_to_background
54+ expect ( configuration . provider ) . to be ( providers [ 2 ] )
55+ end
56+ end
4157 end
4258end
Original file line number Diff line number Diff line change 88
99require "debug"
1010
11+ Dir [ "./spec/support/**/*.rb" ] . sort . each { |f | require f }
12+
1113RSpec . configure do |config |
1214 # Enable flags like --only-failures and --next-failure
1315 config . example_status_persistence_file_path = ".rspec_status"
Original file line number Diff line number Diff line change 1+ # frozen_string_literal: true
2+
3+ module BackgroundHelper
4+ attr_writer :threads
5+
6+ private
7+
8+ def background ( &)
9+ thread = Thread . new ( &)
10+ thread . report_on_exception = false
11+ threads << thread
12+ thread . join ( 0.1 )
13+ thread
14+ end
15+
16+ def threads
17+ @threads ||= [ ]
18+ end
19+
20+ def yield_to_background
21+ threads . each ( &:join )
22+ end
23+ end
24+
25+ RSpec . configure do |config |
26+ config . after do
27+ threads . each ( &:kill )
28+ self . threads = [ ]
29+ end
30+ config . include ( BackgroundHelper )
31+ end
You can’t perform that action at this time.
0 commit comments