diff options
author | Jacob Vosmaer <contact@jacobvosmaer.nl> | 2016-03-18 17:31:53 +0300 |
---|---|---|
committer | Jacob Vosmaer <contact@jacobvosmaer.nl> | 2016-04-04 18:01:56 +0300 |
commit | 213ee62469c6518af8423f00fb902b7665d61204 (patch) | |
tree | 7ccbb292555d28e939be5c1219a05c94d5bcb550 /lib/gitlab | |
parent | 0163e27631fb993bd3541c09a95f0ef5e2026455 (diff) |
Be careful when setting class instance vars
Diffstat (limited to 'lib/gitlab')
-rw-r--r-- | lib/gitlab/redis.rb | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/gitlab/redis.rb b/lib/gitlab/redis.rb index d03e6e4cd92..8c3aea2627c 100644 --- a/lib/gitlab/redis.rb +++ b/lib/gitlab/redis.rb @@ -2,12 +2,23 @@ module Gitlab class Redis attr_reader :url + # To be thread-safe we must be careful when writing the class instance + # variables @url and @pool. Because @pool depends on @url we need two + # mutexes to prevent deadlock. + URL_MUTEX = Mutex.new + POOL_MUTEX = Mutex.new + private_constant :URL_MUTEX, :POOL_MUTEX + def self.url - @url ||= new.url + @url || URL_MUTEX.synchronize { @url = new.url } end def self.with - @pool ||= ConnectionPool.new { ::Redis.new(url: url) } + if @pool.nil? + POOL_MUTEX.synchronize do + @pool = ConnectionPool.new { ::Redis.new(url: url) } + end + end @pool.with { |redis| yield redis } end |