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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +36 -40
  3. data/.github/workflows/release.yml +1 -4
  4. data/.gitignore +2 -2
  5. data/.release-please-manifest.json +1 -1
  6. data/.ruby-version +2 -0
  7. data/.tool-versions +1 -1
  8. data/CHANGELOG.md +51 -0
  9. data/Gemfile +31 -0
  10. data/LICENSE.txt +4 -4
  11. data/Makefile +10 -0
  12. data/README.md +7 -35
  13. data/Rakefile +5 -2
  14. data/bin/console +11 -0
  15. data/bin/rails +15 -0
  16. data/bin/sanity +20 -0
  17. data/bin/sanity_check +86 -0
  18. data/bin/setup +8 -0
  19. data/bin/setup_test_db +59 -0
  20. data/bin/test_connections +22 -0
  21. data/docker-compose.yml +19 -0
  22. data/lib/with_advisory_lock/concern.rb +27 -16
  23. data/lib/with_advisory_lock/core_advisory.rb +110 -0
  24. data/lib/with_advisory_lock/jruby_adapter.rb +29 -0
  25. data/lib/with_advisory_lock/lock_stack_item.rb +6 -0
  26. data/lib/with_advisory_lock/mysql_advisory.rb +62 -0
  27. data/lib/with_advisory_lock/postgresql_advisory.rb +112 -0
  28. data/lib/with_advisory_lock/result.rb +14 -0
  29. data/lib/with_advisory_lock/version.rb +1 -1
  30. data/lib/with_advisory_lock.rb +38 -9
  31. data/test/dummy/Rakefile +8 -0
  32. data/test/dummy/app/controllers/application_controller.rb +7 -0
  33. data/test/dummy/app/models/application_record.rb +6 -0
  34. data/test/dummy/app/models/label.rb +4 -0
  35. data/test/dummy/app/models/mysql_label.rb +5 -0
  36. data/test/dummy/app/models/mysql_record.rb +6 -0
  37. data/test/dummy/app/models/mysql_tag.rb +10 -0
  38. data/test/dummy/app/models/mysql_tag_audit.rb +5 -0
  39. data/test/dummy/app/models/tag.rb +8 -0
  40. data/test/dummy/app/models/tag_audit.rb +4 -0
  41. data/test/dummy/config/application.rb +31 -0
  42. data/test/dummy/config/boot.rb +3 -0
  43. data/test/dummy/config/database.yml +13 -0
  44. data/test/dummy/config/environment.rb +7 -0
  45. data/test/dummy/config/routes.rb +4 -0
  46. data/test/dummy/config.ru +6 -0
  47. data/test/{test_models.rb → dummy/db/schema.rb} +3 -14
  48. data/test/dummy/db/secondary_schema.rb +15 -0
  49. data/test/dummy/lib/tasks/db.rake +40 -0
  50. data/test/sanity_check_test.rb +63 -0
  51. data/test/test_helper.rb +18 -37
  52. data/test/with_advisory_lock/concern_test.rb +79 -0
  53. data/test/with_advisory_lock/lock_test.rb +197 -0
  54. data/test/with_advisory_lock/multi_adapter_test.rb +17 -0
  55. data/test/with_advisory_lock/parallelism_test.rb +101 -0
  56. data/test/with_advisory_lock/postgresql_race_condition_test.rb +118 -0
  57. data/test/with_advisory_lock/shared_test.rb +129 -0
  58. data/test/with_advisory_lock/thread_test.rb +83 -0
  59. data/test/with_advisory_lock/transaction_test.rb +83 -0
  60. data/with_advisory_lock.gemspec +26 -6
  61. metadata +64 -55
  62. data/Appraisals +0 -45
  63. data/gemfiles/activerecord_6.1.gemfile +0 -21
  64. data/gemfiles/activerecord_7.0.gemfile +0 -21
  65. data/gemfiles/activerecord_7.1.gemfile +0 -14
  66. data/lib/with_advisory_lock/base.rb +0 -118
  67. data/lib/with_advisory_lock/database_adapter_support.rb +0 -26
  68. data/lib/with_advisory_lock/flock.rb +0 -33
  69. data/lib/with_advisory_lock/mysql.rb +0 -27
  70. data/lib/with_advisory_lock/postgresql.rb +0 -43
  71. data/test/concern_test.rb +0 -33
  72. data/test/lock_test.rb +0 -80
  73. data/test/nesting_test.rb +0 -28
  74. data/test/options_test.rb +0 -66
  75. data/test/parallelism_test.rb +0 -75
  76. data/test/shared_test.rb +0 -134
  77. data/test/thread_test.rb +0 -61
  78. 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
@@ -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