summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Vosmaer <contact@jacobvosmaer.nl>2016-03-24 13:45:39 +0100
committerJacob Vosmaer <contact@jacobvosmaer.nl>2016-03-24 13:51:33 +0100
commitbe3675c8ac2f362a12252b8bef56b102689be7f2 (patch)
tree2a3bef408d061100cd63fa3df63a94eb5b3faa0a
parentffe5ac41b84c342a8b1d099afe116cb1522da8f2 (diff)
downloadgitlab-ce-lease-design-comments.tar.gz
Explain why ExclusiveLease has no #cancellease-design-comments
[ci skip]
-rw-r--r--lib/gitlab/exclusive_lease.rb21
1 files changed, 21 insertions, 0 deletions
diff --git a/lib/gitlab/exclusive_lease.rb b/lib/gitlab/exclusive_lease.rb
index 2ef50286b1d..c73eca832d7 100644
--- a/lib/gitlab/exclusive_lease.rb
+++ b/lib/gitlab/exclusive_lease.rb
@@ -15,6 +15,25 @@ module Gitlab
# seconds then two overlapping operations may hold a lease for the same
# key at the same time.
#
+ # This class has no 'cancel' method. I originally decided against adding
+ # it because it would add complexity and a false sense of security. The
+ # complexity: instead of setting '1' we would have to set a UUID, and to
+ # delete it we would have to execute Lua on the Redis server to only
+ # delete the key if the value was our own UUID. Otherwise there is a
+ # chance that when you intend to cancel your lease you actually delete
+ # someone else's. The false sense of security: you cannot design your
+ # system to rely too much on the lease being cancelled after use because
+ # the calling (Ruby) process may crash or be killed. You _cannot_ count
+ # on begin/ensure blocks to cancel a lease, because the 'ensure' does
+ # not always run. Think of 'kill -9' from the Unicorn master for
+ # instance.
+ #
+ # If you find that leases are getting in your way, ask yourself: would
+ # it be enough to lower the lease timeout? Another thing that might be
+ # appropriate is to only use a lease for bulk/automated operations, and
+ # to ignore the lease when you get a single 'manual' user request (a
+ # button click).
+ #
class ExclusiveLease
def initialize(key, timeout:)
@key, @timeout = key, timeout
@@ -27,6 +46,8 @@ module Gitlab
!!redis.set(redis_key, '1', nx: true, ex: @timeout)
end
+ # No #cancel method. See comments above!
+
private
def redis