Skip to content

Commit

Permalink
chore: Refactor and optimize MySQL advisory lock handling
Browse files Browse the repository at this point in the history
This commit removes unused MySQL lock variables,
  • Loading branch information
seuros committed Feb 12, 2024
1 parent 3ab0026 commit 1d5d9b4
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 10 deletions.
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.PHONY: test-pg test-mysql

test-pg:
docker compose up -d pg
sleep 10 # give some time for the service to start
DATABASE_URL=postgres://with_advisory:with_advisory_pass@localhost/with_advisory_lock_test appraisal activerecord-7.1 rake test

test-mysql:
docker compose up -d mysql
sleep 10 # give some time for the service to start
DATABASE_URL=mysql2://with_advisory:with_advisory_pass@0.0.0.0:3306/with_advisory_lock_test appraisal activerecord-7.1 rake test


test: test-pg test-mysql
20 changes: 20 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: "3.9"
services:
pg:
image: postgres:16
environment:
POSTGRES_USER: with_advisory
POSTGRES_PASSWORD: with_advisory_pass
POSTGRES_DB: with_advisory_lock_test
ports:
- "5432:5432"
mysql:
image: mysql:8
environment:
MYSQL_USER: with_advisory
MYSQL_PASSWORD: with_advisory_pass
MYSQL_DATABASE: with_advisory_lock_test
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
MYSQL_ROOT_HOST: '%'
ports:
- "3306:3306"
14 changes: 8 additions & 6 deletions lib/with_advisory_lock/mysql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

module WithAdvisoryLock
class MySQL < Base
# Caches nested lock support by MySQL reported version
@@mysql_nl_cache = {}
@@mysql_nl_cache_mutex = Mutex.new
# See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_get-lock
# See https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html
# See https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html
def try_lock
raise ArgumentError, 'shared locks are not supported on MySQL' if shared
raise ArgumentError, 'transaction level locks are not supported on MySQL' if transaction
Expand All @@ -18,8 +16,12 @@ def release_lock
end

def execute_successful?(mysql_function)
sql = "SELECT #{mysql_function} AS #{unique_column_name}"
connection.select_value(sql).to_i.positive?
execute_query(mysql_function) == 1
end

def execute_query(mysql_function)
sql = "SELECT #{mysql_function}"
connection.query_value(sql)
end

# MySQL wants a string as the lock key.
Expand Down
4 changes: 2 additions & 2 deletions test/with_advisory_lock/shared_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def cleanup!
private

def work
ApplicationRecord.connection_pool.with_connection do
Tag.connection_pool.with_connection do
Tag.with_advisory_lock('test', timeout_seconds: 0, shared: @shared) do
@locked = true
sleep 0.01 until @cleanup
Expand Down Expand Up @@ -117,7 +117,7 @@ class PostgreSQLTest < SupportedEnvironmentTest
end

def pg_lock_modes
ApplicationRecord.connection.select_values("SELECT mode FROM pg_locks WHERE locktype = 'advisory';")
Tag.connection.select_values("SELECT mode FROM pg_locks WHERE locktype = 'advisory';")
end

test 'allows shared lock to be upgraded to an exclusive lock' do
Expand Down
4 changes: 2 additions & 2 deletions test/with_advisory_lock/thread_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class SeparateThreadTest < GemTestCase
@t1_return_value = nil

@t1 = Thread.new do
ApplicationRecord.connection_pool.with_connection do
Label.connection_pool.with_connection do
@t1_return_value = Label.with_advisory_lock(@lock_name) do
@mutex.synchronize { @t1_acquired_lock = true }
sleep
Expand All @@ -21,7 +21,7 @@ class SeparateThreadTest < GemTestCase

# Wait for the thread to acquire the lock:
sleep(0.1) until @mutex.synchronize { @t1_acquired_lock }
ApplicationRecord.connection.reconnect!
Label.connection.reconnect!
end

teardown do
Expand Down

0 comments on commit 1d5d9b4

Please sign in to comment.