diff --git a/lib/with_advisory_lock/core_advisory.rb b/lib/with_advisory_lock/core_advisory.rb index d0991e0..4c576b5 100644 --- a/lib/with_advisory_lock/core_advisory.rb +++ b/lib/with_advisory_lock/core_advisory.rb @@ -70,8 +70,8 @@ def advisory_lock_and_yield(lock_name, lock_str, lock_stack_item, options, &) def yield_with_lock_and_timeout(lock_keys, lock_name, lock_str, lock_stack_item, shared, transaction, timeout_seconds, &) - give_up_at = timeout_seconds ? Time.now + timeout_seconds : nil - while give_up_at.nil? || Time.now < give_up_at + give_up_at = timeout_seconds ? Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout_seconds : nil + while give_up_at.nil? || Process.clock_gettime(Process::CLOCK_MONOTONIC) < give_up_at r = yield_with_lock(lock_keys, lock_name, lock_str, lock_stack_item, shared, transaction, 0, &) return r if r.lock_was_acquired? diff --git a/test/with_advisory_lock/lock_test.rb b/test/with_advisory_lock/lock_test.rb index 1b2c528..de39246 100644 --- a/test/with_advisory_lock/lock_test.rb +++ b/test/with_advisory_lock/lock_test.rb @@ -200,13 +200,14 @@ def setup begin # Attempt to acquire with a short timeout - should fail quickly - start_time = Time.now - result = model_class.with_advisory_lock(lock_name, timeout_seconds: 1) { 'success' } - elapsed = Time.now - start_time + elapsed = Benchmark.realtime do + result = model_class.with_advisory_lock(lock_name, timeout_seconds: 1) { 'success' } + + # Should return false and complete within reasonable time (< 3 seconds) + # If it were using Ruby polling, it would take longer + assert_not result + end - # Should return false and complete within reasonable time (< 3 seconds) - # If it were using Ruby polling, it would take longer - assert_not result assert elapsed < 3.0, "Expected quick timeout, but took #{elapsed} seconds" ensure other_conn.query_value("SELECT RELEASE_LOCK(#{other_conn.quote(lock_keys.first)})")