Skip to content

Commit

Permalink
Fix thread safe issues
Browse files Browse the repository at this point in the history
Added a local_config when using `BusinessTime::Config#with`. It copies
the current global config to current thread, apply the wanted
modifications and work as expected inside the block.
Calls to `BusinessTime::Config#config` and `BusinessTime::Config#config=`
will return the local_config if it exists.
  • Loading branch information
Flink committed Jul 7, 2014
1 parent 856e106 commit c332491
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
21 changes: 18 additions & 3 deletions lib/business_time/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,27 @@ class << self
private

def config
return local_config if local_config?
Thread.main[:business_time_config] ||= default_config
end

def config=(config)
return self.local_config = config if local_config?
Thread.main[:business_time_config] = config
end

def local_config
Thread.current[:business_time_local_config]
end

def local_config=(config)
Thread.current[:business_time_local_config] = config
end

def local_config?
!local_config.nil?
end

def threadsafe_cattr_accessor(name)
define_singleton_method name do
config[name]
Expand Down Expand Up @@ -131,11 +145,11 @@ def load(file)
end

def with(config)
old = config().dup
self.local_config = config().dup
config.each { |k,v| send("#{k}=", v) } # calculations are done on setting
yield
ensure
self.config = old
self.local_config = nil
end

def default_config
Expand All @@ -154,7 +168,8 @@ def int_to_wday num
end

def reset
self.config = default_config
self.config = default_config
self.local_config = nil
end

def deep_dup(object)
Expand Down
16 changes: 16 additions & 0 deletions test/test_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,5 +152,21 @@
assert ran
assert_equal "5:00 pm", BusinessTime::Config.end_of_workday
end

it 'is threadsafe' do
old_hours = { fri: ['10:00', '12:00'] }
new_hours = { fri: ['10:00', '13:00'] }
BusinessTime::Config.work_hours = old_hours
t1 = Thread.new do
sleep 0.1
assert_equal BusinessTime::Config.work_hours, old_hours
end
Thread.new do
BusinessTime::Config.with(work_hours: new_hours) do
t1.join
assert_equal BusinessTime::Config.work_hours, new_hours
end
end.join
end
end
end

0 comments on commit c332491

Please sign in to comment.