lib/locker/advisory.rb in locker-0.5.0 vs lib/locker/advisory.rb in locker-0.6.0

- old
+ new

@@ -4,12 +4,16 @@ class Advisory class LockConnectionLost < StandardError; end attr_reader :key, :crc, :lockspace, :blocking, :locked + # The advisory function we use from PostgreSQL needs the arguments to be + # INT, therefore this are the range of int numbers for PostgreSQL MAX_LOCK = 2147483647 MIN_LOCK = -2147483648 + + # Max number that a 32bit computer can hold OVERFLOW_ADJUSTMENT = 2**32 def initialize(key, options={}) raise ArgumentError, "key must be a string" unless key.is_a?(String) @@ -81,28 +85,40 @@ end protected def get(connection) - result = exec_query(connection, "SELECT pg_try_advisory_xact_lock(#{connection.quote(@lockspace)}, #{connection.quote(@crc)})") + lockspace_quote = connection.quote(@lockspace) + crc_quote = connection.quote(@crc) + + result = exec_query( + connection, + "SELECT pg_try_advisory_xact_lock(#{lockspace_quote}, #{crc_quote})" + ) @locked = successful_result?(result) end def check(connection, thread) if !connection.active? @locked = false thread.raise LockConnectionLost end end + # CRC32 digest to get a decimal numeric of the key used, make sure the + # resulting number is within PostgreSql max and min Integer numbers def convert_to_crc(key) crc = Zlib.crc32(key) crc -= OVERFLOW_ADJUSTMENT if crc > MAX_LOCK crc end def successful_result?(result) - result.rows.size == 1 && result.rows[0].size == 1 && result.rows[0][0] == "t" + result.rows.size == 1 && + result.rows[0].size == 1 && ( + result.rows[0][0] == 't' || # Checking for old ActiveRecord + result.rows[0][0].class == TrueClass # Checking for the value true + ) end def exec_query(connection, query) connection.exec_query(query, "Locker::Advisory") end