dv/redis-semaphore

Using an ActiveSupport::Duration for timeouts results in indefinite block

GuyPaddock opened this issue · 0 comments

This issue is related to redis/redis-rb#782.

It appears that trying to use Rails convenience methods on Numeric for seconds, minutes, etc, when passing a timeout into lock will end up with no timeout at all.

For example, something like this will block indefinitely until the lock is released:

my_lock.lock(2.seconds) do
  # work
end

This is because the Redis gem does a switch on the exact class of the last argument to the underlying _bpop method when determining if the timeout argument is present. An ActiveSupport::Duration object pretends to be an Integer/quacks like an Integer for most situations, but does not pass this strict type check.

Based on my findings, it appears that Redis Semaphore could workaround/avoid this issue by passing the timeout as a named argument into blpop, instead of passing it as a positional argument.