From 7c7098c70056e1a3c2a8a9b366a793994b62dee8 Mon Sep 17 00:00:00 2001 From: Daniel Waterworth Date: Mon, 3 Feb 2020 12:23:02 +0000 Subject: [PATCH] FIX: Off-by-one error setting the distributed mutex key to expire Accounting for fractional seconds, a distributed mutex can be held for almost a full second longer than its validity. For example: if we grab the lock at 10.5 seconds passed the epoch with a validity of 5 seconds, the lock would be released at 16 seconds passed the epoch. However, in this case assuming that all other processing takes a negligible amount of time, the key would be expired at 15.5 seconds passed the epoch. Using expireat, the key is now expired exactly when the lock is released. --- lib/distributed_mutex.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/distributed_mutex.rb b/lib/distributed_mutex.rb index 39481f2269a..fed5d91f7de 100644 --- a/lib/distributed_mutex.rb +++ b/lib/distributed_mutex.rb @@ -95,7 +95,7 @@ class DistributedMutex result = redis.multi do redis.set key, expire_time.to_s - redis.expire key, validity + redis.expireat key, expire_time + 1 end got_lock = !result.nil?