with_advisory_lock 4.6.0 → 5.3.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci-mysql5.yml +61 -0
  3. data/.github/workflows/ci-mysql8.yml +62 -0
  4. data/.github/workflows/ci-postgresql.yml +64 -0
  5. data/.github/workflows/ci-sqlite3.yml +54 -0
  6. data/.github/workflows/release.yml +17 -0
  7. data/.gitignore +2 -0
  8. data/.release-please-manifest.json +1 -0
  9. data/.ruby-version +2 -0
  10. data/.tool-versions +1 -1
  11. data/Appraisals +34 -18
  12. data/CHANGELOG.md +50 -0
  13. data/Gemfile +0 -12
  14. data/LICENSE.txt +4 -4
  15. data/Makefile +14 -0
  16. data/README.md +17 -6
  17. data/docker-compose.yml +20 -0
  18. data/gemfiles/{activerecord_6.0.gemfile → activerecord_6.1.gemfile} +4 -2
  19. data/gemfiles/{activerecord_5.2.gemfile → activerecord_7.0.gemfile} +4 -2
  20. data/gemfiles/activerecord_7.1.gemfile +14 -0
  21. data/lib/with_advisory_lock/base.rb +18 -4
  22. data/lib/with_advisory_lock/concern.rb +17 -17
  23. data/lib/with_advisory_lock/database_adapter_support.rb +7 -47
  24. data/lib/with_advisory_lock/failed_to_acquire_lock.rb +9 -0
  25. data/lib/with_advisory_lock/flock.rb +4 -3
  26. data/lib/with_advisory_lock/mysql.rb +12 -7
  27. data/lib/with_advisory_lock/postgresql.rb +43 -18
  28. data/lib/with_advisory_lock/version.rb +3 -1
  29. data/lib/with_advisory_lock.rb +9 -10
  30. data/release-please-config.json +9 -0
  31. data/test/test_helper.rb +66 -0
  32. data/test/test_models.rb +16 -10
  33. data/test/with_advisory_lock/base_test.rb +9 -0
  34. data/test/with_advisory_lock/concern_test.rb +33 -0
  35. data/test/with_advisory_lock/lock_test.rb +111 -0
  36. data/test/with_advisory_lock/nesting_test.rb +28 -0
  37. data/test/with_advisory_lock/options_test.rb +66 -0
  38. data/test/with_advisory_lock/parallelism_test.rb +75 -0
  39. data/test/with_advisory_lock/shared_test.rb +134 -0
  40. data/test/with_advisory_lock/thread_test.rb +61 -0
  41. data/test/with_advisory_lock/transaction_test.rb +68 -0
  42. data/with_advisory_lock.gemspec +29 -23
  43. metadata +56 -47
  44. data/.travis.yml +0 -38
  45. data/gemfiles/activerecord_4.2.gemfile +0 -19
  46. data/gemfiles/activerecord_5.0.gemfile +0 -19
  47. data/gemfiles/activerecord_5.1.gemfile +0 -19
  48. data/lib/with_advisory_lock/mysql_no_nesting.rb +0 -20
  49. data/lib/with_advisory_lock/nested_advisory_lock_error.rb +0 -14
  50. data/test/concern_test.rb +0 -20
  51. data/test/database.yml +0 -17
  52. data/test/lock_test.rb +0 -47
  53. data/test/minitest_helper.rb +0 -40
  54. data/test/nesting_test.rb +0 -93
  55. data/test/options_test.rb +0 -64
  56. data/test/parallelism_test.rb +0 -77
  57. data/test/shared_test.rb +0 -131
  58. data/test/thread_test.rb +0 -60
  59. data/test/transaction_test.rb +0 -70
  60. data/tests.sh +0 -11
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class OptionsParsingTest < GemTestCase
6
+ def parse_options(options)
7
+ WithAdvisoryLock::Base.new(mock, mock, options)
8
+ end
9
+
10
+ test 'defaults (empty hash)' do
11
+ impl = parse_options({})
12
+ assert_nil(impl.timeout_seconds)
13
+ assert_not(impl.shared)
14
+ assert_not(impl.transaction)
15
+ end
16
+
17
+ test 'nil sets timeout to nil' do
18
+ impl = parse_options(nil)
19
+ assert_nil(impl.timeout_seconds)
20
+ assert_not(impl.shared)
21
+ assert_not(impl.transaction)
22
+ end
23
+
24
+ test 'integer sets timeout to value' do
25
+ impl = parse_options(42)
26
+ assert_equal(42, impl.timeout_seconds)
27
+ assert_not(impl.shared)
28
+ assert_not(impl.transaction)
29
+ end
30
+
31
+ test 'hash with invalid key errors' do
32
+ assert_raises(ArgumentError) do
33
+ parse_options(foo: 42)
34
+ end
35
+ end
36
+
37
+ test 'hash with timeout_seconds sets timeout to value' do
38
+ impl = parse_options(timeout_seconds: 123)
39
+ assert_equal(123, impl.timeout_seconds)
40
+ assert_not(impl.shared)
41
+ assert_not(impl.transaction)
42
+ end
43
+
44
+ test 'hash with shared option sets shared to true' do
45
+ impl = parse_options(shared: true)
46
+ assert_nil(impl.timeout_seconds)
47
+ assert(impl.shared)
48
+ assert_not(impl.transaction)
49
+ end
50
+
51
+ test 'hash with transaction option set transaction to true' do
52
+ impl = parse_options(transaction: true)
53
+ assert_nil(impl.timeout_seconds)
54
+ assert_not(impl.shared)
55
+ assert(impl.transaction)
56
+ end
57
+
58
+ test 'hash with multiple keys sets options' do
59
+ foo = mock
60
+ bar = mock
61
+ impl = parse_options(timeout_seconds: foo, shared: bar)
62
+ assert_equal(foo, impl.timeout_seconds)
63
+ assert_equal(bar, impl.shared)
64
+ assert_not(impl.transaction)
65
+ end
66
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'forwardable'
5
+
6
+ class FindOrCreateWorker
7
+ extend Forwardable
8
+ def_delegators :@thread, :join, :wakeup, :status, :to_s
9
+
10
+ def initialize(name, use_advisory_lock)
11
+ @name = name
12
+ @use_advisory_lock = use_advisory_lock
13
+ @thread = Thread.new { work_later }
14
+ end
15
+
16
+ def work_later
17
+ sleep
18
+ ApplicationRecord.connection_pool.with_connection do
19
+ if @use_advisory_lock
20
+ Tag.with_advisory_lock(@name) { work }
21
+ else
22
+ work
23
+ end
24
+ end
25
+ end
26
+
27
+ def work
28
+ Tag.transaction do
29
+ Tag.where(name: @name).first_or_create
30
+ end
31
+ end
32
+ end
33
+
34
+ class ParallelismTest < GemTestCase
35
+ def run_workers
36
+ @names = @iterations.times.map { |iter| "iteration ##{iter}" }
37
+ @names.each do |name|
38
+ workers = @workers.times.map do
39
+ FindOrCreateWorker.new(name, @use_advisory_lock)
40
+ end
41
+ # Wait for all the threads to get ready:
42
+ sleep(0.1) until workers.all? { |ea| ea.status == 'sleep' }
43
+ # OK, GO!
44
+ workers.each(&:wakeup)
45
+ # Then wait for them to finish:
46
+ workers.each(&:join)
47
+ end
48
+ # Ensure we're still connected:
49
+ ApplicationRecord.connection_pool.connection
50
+ end
51
+
52
+ setup do
53
+ ApplicationRecord.connection.reconnect!
54
+ @workers = 10
55
+ end
56
+
57
+ test 'creates multiple duplicate rows without advisory locks' do
58
+ skip if %i[sqlite3 jdbcsqlite3].include?(env_db)
59
+ @use_advisory_lock = false
60
+ @iterations = 1
61
+ run_workers
62
+ assert_operator(Tag.all.size, :>, @iterations) # <- any duplicated rows will make me happy.
63
+ assert_operator(TagAudit.all.size, :>, @iterations) # <- any duplicated rows will make me happy.
64
+ assert_operator(Label.all.size, :>, @iterations) # <- any duplicated rows will make me happy.
65
+ end
66
+
67
+ test "doesn't create multiple duplicate rows with advisory locks" do
68
+ @use_advisory_lock = true
69
+ @iterations = 10
70
+ run_workers
71
+ assert_equal(@iterations, Tag.all.size) # <- any duplicated rows will NOT make me happy.
72
+ assert_equal(@iterations, TagAudit.all.size) # <- any duplicated rows will NOT make me happy.
73
+ assert_equal(@iterations, Label.all.size) # <- any duplicated rows will NOT make me happy.
74
+ end
75
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ class SharedTestWorker
5
+ def initialize(shared)
6
+ @shared = shared
7
+
8
+ @locked = nil
9
+ @cleanup = false
10
+ @thread = Thread.new { work }
11
+ end
12
+
13
+ def locked?
14
+ sleep 0.01 while @locked.nil? && @thread.alive?
15
+ @locked
16
+ end
17
+
18
+ def cleanup!
19
+ @cleanup = true
20
+ @thread.join
21
+ raise if @thread.status.nil?
22
+ end
23
+
24
+ private
25
+
26
+ def work
27
+ Tag.connection_pool.with_connection do
28
+ Tag.with_advisory_lock('test', timeout_seconds: 0, shared: @shared) do
29
+ @locked = true
30
+ sleep 0.01 until @cleanup
31
+ end
32
+ @locked = false
33
+ sleep 0.01 until @cleanup
34
+ end
35
+ end
36
+ end
37
+
38
+ class SharedLocksTest < GemTestCase
39
+ def supported?
40
+ %i[trilogy mysql2 jdbcmysql].exclude?(env_db)
41
+ end
42
+
43
+ test 'does not allow two exclusive locks' do
44
+ one = SharedTestWorker.new(false)
45
+ assert_predicate(one, :locked?)
46
+
47
+ two = SharedTestWorker.new(false)
48
+ refute(two.locked?)
49
+
50
+ one.cleanup!
51
+ two.cleanup!
52
+ end
53
+ end
54
+
55
+ class NotSupportedEnvironmentTest < SharedLocksTest
56
+ setup do
57
+ skip if supported?
58
+ end
59
+
60
+ test 'raises an error when attempting to use a shared lock' do
61
+ one = SharedTestWorker.new(true)
62
+ assert_nil(one.locked?)
63
+
64
+ exception = assert_raises(ArgumentError) do
65
+ one.cleanup!
66
+ end
67
+
68
+ assert_match(/#{Regexp.escape('not supported')}/, exception.message)
69
+ end
70
+ end
71
+
72
+ class SupportedEnvironmentTest < SharedLocksTest
73
+ setup do
74
+ skip unless supported?
75
+ end
76
+
77
+ test 'does allow two shared locks' do
78
+ one = SharedTestWorker.new(true)
79
+ assert_predicate(one, :locked?)
80
+
81
+ two = SharedTestWorker.new(true)
82
+ assert_predicate(two, :locked?)
83
+
84
+ one.cleanup!
85
+ two.cleanup!
86
+ end
87
+
88
+ test 'does not allow exclusive lock with shared lock' do
89
+ one = SharedTestWorker.new(true)
90
+ assert_predicate(one, :locked?)
91
+
92
+ two = SharedTestWorker.new(false)
93
+ refute(two.locked?)
94
+
95
+ three = SharedTestWorker.new(true)
96
+ assert_predicate(three, :locked?)
97
+
98
+ one.cleanup!
99
+ two.cleanup!
100
+ three.cleanup!
101
+ end
102
+
103
+ test 'does not allow shared lock with exclusive lock' do
104
+ one = SharedTestWorker.new(false)
105
+ assert_predicate(one, :locked?)
106
+
107
+ two = SharedTestWorker.new(true)
108
+ refute(two.locked?)
109
+
110
+ one.cleanup!
111
+ two.cleanup!
112
+ end
113
+
114
+ class PostgreSQLTest < SupportedEnvironmentTest
115
+ setup do
116
+ skip unless env_db == :postgresql
117
+ end
118
+
119
+ def pg_lock_modes
120
+ Tag.connection.select_values("SELECT mode FROM pg_locks WHERE locktype = 'advisory';")
121
+ end
122
+
123
+ test 'allows shared lock to be upgraded to an exclusive lock' do
124
+ assert_empty(pg_lock_modes)
125
+ Tag.with_advisory_lock 'test', shared: true do
126
+ assert_equal(%w[ShareLock], pg_lock_modes)
127
+ Tag.with_advisory_lock 'test', shared: false do
128
+ assert_equal(%w[ShareLock ExclusiveLock], pg_lock_modes)
129
+ end
130
+ end
131
+ assert_empty(pg_lock_modes)
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,61 @@
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
+ Label.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
+ Label.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
@@ -0,0 +1,68 @@
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
+ ApplicationRecord.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
@@ -1,29 +1,35 @@
1
- lib = File.expand_path('../lib', __FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'with_advisory_lock/version'
1
+ # frozen_string_literal: true
4
2
 
5
- Gem::Specification.new do |gem|
6
- gem.name = "with_advisory_lock"
7
- gem.version = WithAdvisoryLock::VERSION
8
- gem.authors = ['Matthew McEachen']
9
- gem.email = %w(matthew+github@mceachen.org)
10
- gem.homepage = 'https://github.com/mceachen/with_advisory_lock'
11
- gem.summary = %q{Advisory locking for ActiveRecord}
12
- gem.description = %q{Advisory locking for ActiveRecord}
13
- gem.license = 'MIT'
3
+ require 'English'
4
+ require_relative 'lib/with_advisory_lock/version'
14
5
 
15
- gem.files = `git ls-files`.split($/)
16
- gem.test_files = gem.files.grep(%r{^test/})
17
- gem.require_paths = %w(lib)
18
- gem.required_ruby_version = '>= 2.2.10'
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'with_advisory_lock'
8
+ spec.version = WithAdvisoryLock::VERSION
9
+ spec.authors = ['Matthew McEachen', 'Abdelkader Boudih']
10
+ spec.email = %w[matthew+github@mceachen.org terminale@gmail.com]
11
+ spec.homepage = 'https://github.com/ClosureTree/with_advisory_lock'
12
+ spec.summary = 'Advisory locking for ActiveRecord'
13
+ spec.description = 'Advisory locking for ActiveRecord'
14
+ spec.license = 'MIT'
19
15
 
20
- gem.add_runtime_dependency 'activerecord', '>= 4.2'
16
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
+ spec.test_files = spec.files.grep(%r{^test/})
18
+ spec.require_paths = %w[lib]
19
+ spec.metadata = { 'rubygems_mfa_required' => 'true' }
20
+ spec.required_ruby_version = '>= 2.7.0'
21
+ spec.metadata['yard.run'] = 'yri'
21
22
 
23
+ spec.metadata['homepage_uri'] = spec.homepage
24
+ spec.metadata['source_code_uri'] = 'https://github.com/ClosureTree/with_advisory_lock'
25
+ spec.metadata['changelog_uri'] = 'https://github.com/ClosureTree/with_advisory_lock/blob/master/CHANGELOG.md'
22
26
 
23
- gem.add_development_dependency 'yard'
24
- gem.add_development_dependency 'minitest'
25
- gem.add_development_dependency 'minitest-great_expectations'
26
- gem.add_development_dependency 'minitest-reporters'
27
- gem.add_development_dependency 'mocha'
28
- gem.add_development_dependency 'appraisal'
27
+ spec.add_runtime_dependency 'activerecord', '>= 6.1'
28
+ spec.add_runtime_dependency 'zeitwerk', '>= 2.6'
29
+
30
+ spec.add_development_dependency 'appraisal'
31
+ spec.add_development_dependency 'maxitest'
32
+ spec.add_development_dependency 'minitest-reporters'
33
+ spec.add_development_dependency 'mocha'
34
+ spec.add_development_dependency 'yard'
29
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: with_advisory_lock
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.6.0
4
+ version: 5.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew McEachen
8
- autorequire:
8
+ - Abdelkader Boudih
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-20 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,30 +16,30 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '6.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.2'
26
+ version: '6.1'
27
27
  - !ruby/object:Gem::Dependency
28
- name: yard
28
+ name: zeitwerk
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
33
+ version: '2.6'
34
+ type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '2.6'
41
41
  - !ruby/object:Gem::Dependency
42
- name: minitest
42
+ name: appraisal
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: minitest-great_expectations
56
+ name: maxitest
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: appraisal
98
+ name: yard
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -111,52 +111,62 @@ dependencies:
111
111
  description: Advisory locking for ActiveRecord
112
112
  email:
113
113
  - matthew+github@mceachen.org
114
+ - terminale@gmail.com
114
115
  executables: []
115
116
  extensions: []
116
117
  extra_rdoc_files: []
117
118
  files:
119
+ - ".github/workflows/ci-mysql5.yml"
120
+ - ".github/workflows/ci-mysql8.yml"
121
+ - ".github/workflows/ci-postgresql.yml"
122
+ - ".github/workflows/ci-sqlite3.yml"
123
+ - ".github/workflows/release.yml"
118
124
  - ".gitignore"
125
+ - ".release-please-manifest.json"
126
+ - ".ruby-version"
119
127
  - ".tool-versions"
120
- - ".travis.yml"
121
128
  - Appraisals
122
129
  - CHANGELOG.md
123
130
  - Gemfile
124
131
  - LICENSE.txt
132
+ - Makefile
125
133
  - README.md
126
134
  - Rakefile
127
- - gemfiles/activerecord_4.2.gemfile
128
- - gemfiles/activerecord_5.0.gemfile
129
- - gemfiles/activerecord_5.1.gemfile
130
- - gemfiles/activerecord_5.2.gemfile
131
- - gemfiles/activerecord_6.0.gemfile
135
+ - docker-compose.yml
136
+ - gemfiles/activerecord_6.1.gemfile
137
+ - gemfiles/activerecord_7.0.gemfile
138
+ - gemfiles/activerecord_7.1.gemfile
132
139
  - lib/with_advisory_lock.rb
133
140
  - lib/with_advisory_lock/base.rb
134
141
  - lib/with_advisory_lock/concern.rb
135
142
  - lib/with_advisory_lock/database_adapter_support.rb
143
+ - lib/with_advisory_lock/failed_to_acquire_lock.rb
136
144
  - lib/with_advisory_lock/flock.rb
137
145
  - lib/with_advisory_lock/mysql.rb
138
- - lib/with_advisory_lock/mysql_no_nesting.rb
139
- - lib/with_advisory_lock/nested_advisory_lock_error.rb
140
146
  - lib/with_advisory_lock/postgresql.rb
141
147
  - lib/with_advisory_lock/version.rb
142
- - test/concern_test.rb
143
- - test/database.yml
144
- - test/lock_test.rb
145
- - test/minitest_helper.rb
146
- - test/nesting_test.rb
147
- - test/options_test.rb
148
- - test/parallelism_test.rb
149
- - test/shared_test.rb
148
+ - release-please-config.json
149
+ - test/test_helper.rb
150
150
  - test/test_models.rb
151
- - test/thread_test.rb
152
- - test/transaction_test.rb
153
- - tests.sh
151
+ - test/with_advisory_lock/base_test.rb
152
+ - test/with_advisory_lock/concern_test.rb
153
+ - test/with_advisory_lock/lock_test.rb
154
+ - test/with_advisory_lock/nesting_test.rb
155
+ - test/with_advisory_lock/options_test.rb
156
+ - test/with_advisory_lock/parallelism_test.rb
157
+ - test/with_advisory_lock/shared_test.rb
158
+ - test/with_advisory_lock/thread_test.rb
159
+ - test/with_advisory_lock/transaction_test.rb
154
160
  - with_advisory_lock.gemspec
155
- homepage: https://github.com/mceachen/with_advisory_lock
161
+ homepage: https://github.com/ClosureTree/with_advisory_lock
156
162
  licenses:
157
163
  - MIT
158
- metadata: {}
159
- post_install_message:
164
+ metadata:
165
+ rubygems_mfa_required: 'true'
166
+ yard.run: yri
167
+ homepage_uri: https://github.com/ClosureTree/with_advisory_lock
168
+ source_code_uri: https://github.com/ClosureTree/with_advisory_lock
169
+ changelog_uri: https://github.com/ClosureTree/with_advisory_lock/blob/master/CHANGELOG.md
160
170
  rdoc_options: []
161
171
  require_paths:
162
172
  - lib
@@ -164,26 +174,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
164
174
  requirements:
165
175
  - - ">="
166
176
  - !ruby/object:Gem::Version
167
- version: 2.2.10
177
+ version: 2.7.0
168
178
  required_rubygems_version: !ruby/object:Gem::Requirement
169
179
  requirements:
170
180
  - - ">="
171
181
  - !ruby/object:Gem::Version
172
182
  version: '0'
173
183
  requirements: []
174
- rubygems_version: 3.0.3
175
- signing_key:
184
+ rubygems_version: 3.6.7
176
185
  specification_version: 4
177
186
  summary: Advisory locking for ActiveRecord
178
187
  test_files:
179
- - test/concern_test.rb
180
- - test/database.yml
181
- - test/lock_test.rb
182
- - test/minitest_helper.rb
183
- - test/nesting_test.rb
184
- - test/options_test.rb
185
- - test/parallelism_test.rb
186
- - test/shared_test.rb
188
+ - test/test_helper.rb
187
189
  - test/test_models.rb
188
- - test/thread_test.rb
189
- - test/transaction_test.rb
190
+ - test/with_advisory_lock/base_test.rb
191
+ - test/with_advisory_lock/concern_test.rb
192
+ - test/with_advisory_lock/lock_test.rb
193
+ - test/with_advisory_lock/nesting_test.rb
194
+ - test/with_advisory_lock/options_test.rb
195
+ - test/with_advisory_lock/parallelism_test.rb
196
+ - test/with_advisory_lock/shared_test.rb
197
+ - test/with_advisory_lock/thread_test.rb
198
+ - test/with_advisory_lock/transaction_test.rb
data/.travis.yml DELETED
@@ -1,38 +0,0 @@
1
- language: ruby
2
-
3
- services:
4
- - postgresql
5
- - mysql
6
-
7
- addons:
8
- postgresql: "10"
9
-
10
- rvm:
11
- - 2.6.4
12
- - 2.5.6
13
- - 2.4.7
14
-
15
- gemfile:
16
- - gemfiles/activerecord_6.0.gemfile
17
- - gemfiles/activerecord_5.2.gemfile
18
- - gemfiles/activerecord_5.1.gemfile
19
- - gemfiles/activerecord_5.0.gemfile
20
- - gemfiles/activerecord_4.2.gemfile
21
-
22
- env:
23
- global:
24
- - WITH_ADVISORY_LOCK_PREFIX=$TRAVIS_JOB_ID
25
- matrix:
26
- - DB=postgresql
27
- - DB=mysql MYSQL_VERSION=5.7
28
- - DB=sqlite
29
- matrix:
30
- exclude:
31
- - rvm: 2.4.7
32
- gemfile: gemfiles/activerecord_6.0.gemfile
33
-
34
- before_install:
35
- - mysql -e 'create database with_advisory_lock_test'
36
- - psql -c 'create database with_advisory_lock_test' -U postgres
37
-
38
- script: bundle exec rake --trace