diff options
author | Jacob Vosmaer <contact@jacobvosmaer.nl> | 2016-03-10 12:41:16 +0300 |
---|---|---|
committer | Jacob Vosmaer <contact@jacobvosmaer.nl> | 2016-03-10 12:41:16 +0300 |
commit | cda0b7e1b142130fd2e4d7073e451a3f8d73b693 (patch) | |
tree | 0d60230f7a4b3bbaab4d5d21e75a837fe1685801 /lib/gitlab/exclusive_lease.rb | |
parent | acd9bc0213098a5626499021eb72595eb556f9be (diff) |
Rename ExpiringLock to ExclusiveLease
Diffstat (limited to 'lib/gitlab/exclusive_lease.rb')
-rw-r--r-- | lib/gitlab/exclusive_lease.rb | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/gitlab/exclusive_lease.rb b/lib/gitlab/exclusive_lease.rb new file mode 100644 index 00000000000..f801e8b60b3 --- /dev/null +++ b/lib/gitlab/exclusive_lease.rb @@ -0,0 +1,37 @@ +require 'securerandom' + +module Gitlab + # This class implements an 'exclusive lease'. We call it a 'lease' + # because it has a set expiry time. We call it 'exclusive' because only + # one caller may obtain a lease for a given key at a time. The + # implementation is intended to work across GitLab processes and across + # servers. It is a 'cheap' alternative to using SQL queries and updates: + # you do not need to change the SQL schema to start using + # ExclusiveLease. + class ExclusiveLease + def initialize(key, timeout) + @key, @timeout = key, timeout + end + + # Try to obtain the lease. Return true on succes, + # false if the lease is already taken. + def try_obtain + !!redis.set(redis_key, redis_value, nx: true, ex: @timeout) + end + + private + + def redis + # Maybe someday we want to use a connection pool... + @redis ||= Redis.new(url: Gitlab::RedisConfig.url) + end + + def redis_key + "gitlab:exclusive_lease:#{@key}" + end + + def redis_value + @redis_value ||= SecureRandom.hex(10) + end + end +end |