with_advisory_lock 5.1.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +36 -40
- data/.github/workflows/release.yml +1 -4
- data/.gitignore +2 -2
- data/.release-please-manifest.json +1 -1
- data/.ruby-version +2 -0
- data/.tool-versions +1 -1
- data/CHANGELOG.md +51 -0
- data/Gemfile +31 -0
- data/LICENSE.txt +4 -4
- data/Makefile +10 -0
- data/README.md +7 -35
- data/Rakefile +5 -2
- data/bin/console +11 -0
- data/bin/rails +15 -0
- data/bin/sanity +20 -0
- data/bin/sanity_check +86 -0
- data/bin/setup +8 -0
- data/bin/setup_test_db +59 -0
- data/bin/test_connections +22 -0
- data/docker-compose.yml +19 -0
- data/lib/with_advisory_lock/concern.rb +27 -16
- data/lib/with_advisory_lock/core_advisory.rb +110 -0
- data/lib/with_advisory_lock/jruby_adapter.rb +29 -0
- data/lib/with_advisory_lock/lock_stack_item.rb +6 -0
- data/lib/with_advisory_lock/mysql_advisory.rb +62 -0
- data/lib/with_advisory_lock/postgresql_advisory.rb +112 -0
- data/lib/with_advisory_lock/result.rb +14 -0
- data/lib/with_advisory_lock/version.rb +1 -1
- data/lib/with_advisory_lock.rb +38 -9
- data/test/dummy/Rakefile +8 -0
- data/test/dummy/app/controllers/application_controller.rb +7 -0
- data/test/dummy/app/models/application_record.rb +6 -0
- data/test/dummy/app/models/label.rb +4 -0
- data/test/dummy/app/models/mysql_label.rb +5 -0
- data/test/dummy/app/models/mysql_record.rb +6 -0
- data/test/dummy/app/models/mysql_tag.rb +10 -0
- data/test/dummy/app/models/mysql_tag_audit.rb +5 -0
- data/test/dummy/app/models/tag.rb +8 -0
- data/test/dummy/app/models/tag_audit.rb +4 -0
- data/test/dummy/config/application.rb +31 -0
- data/test/dummy/config/boot.rb +3 -0
- data/test/dummy/config/database.yml +13 -0
- data/test/dummy/config/environment.rb +7 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config.ru +6 -0
- data/test/{test_models.rb → dummy/db/schema.rb} +3 -14
- data/test/dummy/db/secondary_schema.rb +15 -0
- data/test/dummy/lib/tasks/db.rake +40 -0
- data/test/sanity_check_test.rb +63 -0
- data/test/test_helper.rb +18 -37
- data/test/with_advisory_lock/concern_test.rb +79 -0
- data/test/with_advisory_lock/lock_test.rb +197 -0
- data/test/with_advisory_lock/multi_adapter_test.rb +17 -0
- data/test/with_advisory_lock/parallelism_test.rb +101 -0
- data/test/with_advisory_lock/postgresql_race_condition_test.rb +118 -0
- data/test/with_advisory_lock/shared_test.rb +129 -0
- data/test/with_advisory_lock/thread_test.rb +83 -0
- data/test/with_advisory_lock/transaction_test.rb +83 -0
- data/with_advisory_lock.gemspec +26 -6
- metadata +64 -55
- data/Appraisals +0 -45
- data/gemfiles/activerecord_6.1.gemfile +0 -21
- data/gemfiles/activerecord_7.0.gemfile +0 -21
- data/gemfiles/activerecord_7.1.gemfile +0 -14
- data/lib/with_advisory_lock/base.rb +0 -118
- data/lib/with_advisory_lock/database_adapter_support.rb +0 -26
- data/lib/with_advisory_lock/flock.rb +0 -33
- data/lib/with_advisory_lock/mysql.rb +0 -27
- data/lib/with_advisory_lock/postgresql.rb +0 -43
- data/test/concern_test.rb +0 -33
- data/test/lock_test.rb +0 -80
- data/test/nesting_test.rb +0 -28
- data/test/options_test.rb +0 -66
- data/test/parallelism_test.rb +0 -75
- data/test/shared_test.rb +0 -134
- data/test/thread_test.rb +0 -61
- data/test/transaction_test.rb +0 -68
data/test/thread_test.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
|
5
|
-
class SeparateThreadTest < GemTestCase
|
6
|
-
setup do
|
7
|
-
@lock_name = 'testing 1,2,3' # OMG COMMAS
|
8
|
-
@mutex = Mutex.new
|
9
|
-
@t1_acquired_lock = false
|
10
|
-
@t1_return_value = nil
|
11
|
-
|
12
|
-
@t1 = Thread.new do
|
13
|
-
ActiveRecord::Base.connection_pool.with_connection do
|
14
|
-
@t1_return_value = Label.with_advisory_lock(@lock_name) do
|
15
|
-
@mutex.synchronize { @t1_acquired_lock = true }
|
16
|
-
sleep
|
17
|
-
't1 finished'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Wait for the thread to acquire the lock:
|
23
|
-
sleep(0.1) until @mutex.synchronize { @t1_acquired_lock }
|
24
|
-
ActiveRecord::Base.connection.reconnect!
|
25
|
-
end
|
26
|
-
|
27
|
-
teardown do
|
28
|
-
@t1.wakeup if @t1.status == 'sleep'
|
29
|
-
@t1.join
|
30
|
-
end
|
31
|
-
|
32
|
-
test '#with_advisory_lock with a 0 timeout returns false immediately' do
|
33
|
-
response = Label.with_advisory_lock(@lock_name, 0) do
|
34
|
-
raise 'should not be yielded to'
|
35
|
-
end
|
36
|
-
assert_not(response)
|
37
|
-
end
|
38
|
-
|
39
|
-
test '#with_advisory_lock yields to the provided block' do
|
40
|
-
assert(@t1_acquired_lock)
|
41
|
-
end
|
42
|
-
|
43
|
-
test '#advisory_lock_exists? returns true when another thread has the lock' do
|
44
|
-
assert(Tag.advisory_lock_exists?(@lock_name))
|
45
|
-
end
|
46
|
-
|
47
|
-
test 'can re-establish the lock after the other thread releases it' do
|
48
|
-
@t1.wakeup
|
49
|
-
@t1.join
|
50
|
-
assert_equal('t1 finished', @t1_return_value)
|
51
|
-
|
52
|
-
# We should now be able to acquire the lock immediately:
|
53
|
-
reacquired = false
|
54
|
-
lock_result = Label.with_advisory_lock(@lock_name, 0) do
|
55
|
-
reacquired = true
|
56
|
-
end
|
57
|
-
|
58
|
-
assert(lock_result)
|
59
|
-
assert(reacquired)
|
60
|
-
end
|
61
|
-
end
|
data/test/transaction_test.rb
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
|
5
|
-
class TransactionScopingTest < GemTestCase
|
6
|
-
def supported?
|
7
|
-
%i[postgresql jdbcpostgresql].include?(env_db)
|
8
|
-
end
|
9
|
-
|
10
|
-
test 'raises an error when attempting to use transaction level locks if not supported' do
|
11
|
-
skip if supported?
|
12
|
-
|
13
|
-
Tag.transaction do
|
14
|
-
exception = assert_raises(ArgumentError) do
|
15
|
-
Tag.with_advisory_lock 'test', transaction: true do
|
16
|
-
raise 'should not get here'
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
assert_match(/#{Regexp.escape('not supported')}/, exception.message)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class PostgresqlTest < TransactionScopingTest
|
25
|
-
setup do
|
26
|
-
skip unless env_db == :postgresql
|
27
|
-
@pg_lock_count = lambda do
|
28
|
-
ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM pg_locks WHERE locktype = 'advisory';").to_i
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
test 'session locks release after the block executes' do
|
33
|
-
Tag.transaction do
|
34
|
-
assert_equal(0, @pg_lock_count.call)
|
35
|
-
Tag.with_advisory_lock 'test' do
|
36
|
-
assert_equal(1, @pg_lock_count.call)
|
37
|
-
end
|
38
|
-
assert_equal(0, @pg_lock_count.call)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
test 'session locks release when transaction fails inside block' do
|
43
|
-
Tag.transaction do
|
44
|
-
assert_equal(0, @pg_lock_count.call)
|
45
|
-
|
46
|
-
exception = assert_raises(ActiveRecord::StatementInvalid) do
|
47
|
-
Tag.with_advisory_lock 'test' do
|
48
|
-
Tag.connection.execute 'SELECT 1/0;'
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
assert_match(/#{Regexp.escape('division by zero')}/, exception.message)
|
53
|
-
assert_equal(0, @pg_lock_count.call)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
test 'transaction level locks hold until the transaction completes' do
|
58
|
-
Tag.transaction do
|
59
|
-
assert_equal(0, @pg_lock_count.call)
|
60
|
-
Tag.with_advisory_lock 'test', transaction: true do
|
61
|
-
assert_equal(1, @pg_lock_count.call)
|
62
|
-
end
|
63
|
-
assert_equal(1, @pg_lock_count.call)
|
64
|
-
end
|
65
|
-
assert_equal(0, @pg_lock_count.call)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|