with_advisory_lock 4.6.0 → 5.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 +80 -0
- data/.gitignore +2 -0
- data/.tool-versions +1 -1
- data/Appraisals +34 -18
- data/CHANGELOG.md +9 -0
- data/Gemfile +0 -12
- data/README.md +17 -6
- data/gemfiles/{activerecord_6.0.gemfile → activerecord_6.1.gemfile} +4 -2
- data/gemfiles/{activerecord_5.2.gemfile → activerecord_7.0.gemfile} +4 -2
- data/gemfiles/activerecord_7.1.gemfile +14 -0
- data/lib/with_advisory_lock/base.rb +16 -2
- data/lib/with_advisory_lock/concern.rb +16 -16
- data/lib/with_advisory_lock/database_adapter_support.rb +4 -41
- data/lib/with_advisory_lock/failed_to_acquire_lock.rb +7 -0
- data/lib/with_advisory_lock/flock.rb +4 -3
- data/lib/with_advisory_lock/mysql.rb +5 -5
- data/lib/with_advisory_lock/postgresql.rb +9 -7
- data/lib/with_advisory_lock/version.rb +3 -1
- data/lib/with_advisory_lock.rb +1 -2
- data/test/concern_test.rb +23 -10
- data/test/lock_test.rb +61 -28
- data/test/nesting_test.rb +14 -79
- data/test/options_test.rb +35 -33
- data/test/parallelism_test.rb +35 -37
- data/test/shared_test.rb +93 -90
- data/test/test_helper.rb +52 -0
- data/test/test_models.rb +9 -7
- data/test/thread_test.rb +23 -22
- data/test/transaction_test.rb +34 -36
- data/with_advisory_lock.gemspec +24 -23
- metadata +25 -41
- data/.travis.yml +0 -38
- data/gemfiles/activerecord_4.2.gemfile +0 -19
- data/gemfiles/activerecord_5.0.gemfile +0 -19
- data/gemfiles/activerecord_5.1.gemfile +0 -19
- data/lib/with_advisory_lock/mysql_no_nesting.rb +0 -20
- data/lib/with_advisory_lock/nested_advisory_lock_error.rb +0 -14
- data/test/database.yml +0 -17
- data/test/minitest_helper.rb +0 -40
- data/tests.sh +0 -11
data/test/test_helper.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'active_record'
|
5
|
+
require 'with_advisory_lock'
|
6
|
+
require 'tmpdir'
|
7
|
+
require 'securerandom'
|
8
|
+
begin
|
9
|
+
require 'activerecord-trilogy-adapter'
|
10
|
+
ActiveSupport.on_load(:active_record) do
|
11
|
+
require "trilogy_adapter/connection"
|
12
|
+
ActiveRecord::Base.public_send :extend, TrilogyAdapter::Connection
|
13
|
+
end
|
14
|
+
rescue LoadError
|
15
|
+
# do nothing
|
16
|
+
end
|
17
|
+
|
18
|
+
ActiveRecord::Base.configurations = {
|
19
|
+
default_env: {
|
20
|
+
url: ENV.fetch('DATABASE_URL', "sqlite3://#{Dir.tmpdir}/#{SecureRandom.hex}.sqlite3"),
|
21
|
+
properties: { allowPublicKeyRetrieval: true } # for JRuby madness
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
ENV['WITH_ADVISORY_LOCK_PREFIX'] ||= SecureRandom.hex
|
26
|
+
|
27
|
+
ActiveRecord::Base.establish_connection
|
28
|
+
|
29
|
+
def env_db
|
30
|
+
@env_db ||= ActiveRecord::Base.connection_db_config.adapter.to_sym
|
31
|
+
end
|
32
|
+
|
33
|
+
ActiveRecord::Migration.verbose = false
|
34
|
+
|
35
|
+
require 'test_models'
|
36
|
+
require 'minitest'
|
37
|
+
require 'maxitest/autorun'
|
38
|
+
require 'mocha/minitest'
|
39
|
+
|
40
|
+
class GemTestCase < ActiveSupport::TestCase
|
41
|
+
setup do
|
42
|
+
ENV['FLOCK_DIR'] = Dir.mktmpdir
|
43
|
+
Tag.delete_all
|
44
|
+
TagAudit.delete_all
|
45
|
+
Label.delete_all
|
46
|
+
end
|
47
|
+
teardown do
|
48
|
+
FileUtils.remove_entry_secure ENV['FLOCK_DIR']
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
puts "Testing with #{env_db} database, ActiveRecord #{ActiveRecord.gem_version} and #{RUBY_ENGINE} #{RUBY_ENGINE_VERSION} as #{RUBY_VERSION}"
|
data/test/test_models.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
ActiveRecord::Schema.define(version: 0) do
|
4
|
+
create_table 'tags', force: true do |t|
|
5
|
+
t.string 'name'
|
4
6
|
end
|
5
|
-
create_table
|
6
|
-
t.string
|
7
|
+
create_table 'tag_audits', id: false, force: true do |t|
|
8
|
+
t.string 'tag_name'
|
7
9
|
end
|
8
|
-
create_table
|
9
|
-
t.string
|
10
|
+
create_table 'labels', id: false, force: true do |t|
|
11
|
+
t.string 'name'
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
data/test/thread_test.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
let(:lock_name) { 'testing 1,2,3' } # OMG COMMAS
|
3
|
+
require 'test_helper'
|
5
4
|
|
6
|
-
|
5
|
+
class SeparateThreadTest < GemTestCase
|
6
|
+
setup do
|
7
|
+
@lock_name = 'testing 1,2,3' # OMG COMMAS
|
7
8
|
@mutex = Mutex.new
|
8
9
|
@t1_acquired_lock = false
|
9
10
|
@t1_return_value = nil
|
10
11
|
|
11
12
|
@t1 = Thread.new do
|
12
13
|
ActiveRecord::Base.connection_pool.with_connection do
|
13
|
-
@t1_return_value = Label.with_advisory_lock(lock_name) do
|
14
|
+
@t1_return_value = Label.with_advisory_lock(@lock_name) do
|
14
15
|
@mutex.synchronize { @t1_acquired_lock = true }
|
15
16
|
sleep
|
16
17
|
't1 finished'
|
@@ -19,42 +20,42 @@ describe 'separate thread tests' do
|
|
19
20
|
end
|
20
21
|
|
21
22
|
# Wait for the thread to acquire the lock:
|
22
|
-
until @mutex.synchronize { @t1_acquired_lock }
|
23
|
-
sleep(0.1)
|
24
|
-
end
|
23
|
+
sleep(0.1) until @mutex.synchronize { @t1_acquired_lock }
|
25
24
|
ActiveRecord::Base.connection.reconnect!
|
26
25
|
end
|
27
26
|
|
28
|
-
|
27
|
+
teardown do
|
29
28
|
@t1.wakeup if @t1.status == 'sleep'
|
30
29
|
@t1.join
|
31
30
|
end
|
32
31
|
|
33
|
-
|
34
|
-
response = Label.with_advisory_lock(lock_name, 0) do
|
35
|
-
|
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'
|
36
35
|
end
|
37
|
-
response
|
36
|
+
assert_not(response)
|
38
37
|
end
|
39
38
|
|
40
|
-
|
41
|
-
@t1_acquired_lock
|
39
|
+
test '#with_advisory_lock yields to the provided block' do
|
40
|
+
assert(@t1_acquired_lock)
|
42
41
|
end
|
43
42
|
|
44
|
-
|
45
|
-
Tag.advisory_lock_exists?(lock_name)
|
43
|
+
test '#advisory_lock_exists? returns true when another thread has the lock' do
|
44
|
+
assert(Tag.advisory_lock_exists?(@lock_name))
|
46
45
|
end
|
47
46
|
|
48
|
-
|
47
|
+
test 'can re-establish the lock after the other thread releases it' do
|
49
48
|
@t1.wakeup
|
50
49
|
@t1.join
|
51
|
-
|
50
|
+
assert_equal('t1 finished', @t1_return_value)
|
52
51
|
|
53
52
|
# We should now be able to acquire the lock immediately:
|
54
53
|
reacquired = false
|
55
|
-
Label.with_advisory_lock(lock_name, 0) do
|
54
|
+
lock_result = Label.with_advisory_lock(@lock_name, 0) do
|
56
55
|
reacquired = true
|
57
|
-
end
|
58
|
-
|
56
|
+
end
|
57
|
+
|
58
|
+
assert(lock_result)
|
59
|
+
assert(reacquired)
|
59
60
|
end
|
60
61
|
end
|
data/test/transaction_test.rb
CHANGED
@@ -1,70 +1,68 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TransactionScopingTest < GemTestCase
|
4
6
|
def supported?
|
5
|
-
env_db
|
7
|
+
%i[postgresql jdbcpostgresql].include?(env_db)
|
6
8
|
end
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
skip if supported?
|
11
|
-
end
|
10
|
+
test 'raises an error when attempting to use transaction level locks if not supported' do
|
11
|
+
skip if supported?
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
}.must_raise ArgumentError
|
20
|
-
exception.message.must_include 'not supported'
|
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
|
21
18
|
end
|
19
|
+
|
20
|
+
assert_match(/#{Regexp.escape('not supported')}/, exception.message)
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
25
|
-
|
26
|
-
|
24
|
+
class PostgresqlTest < TransactionScopingTest
|
25
|
+
setup do
|
27
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
|
28
30
|
end
|
29
31
|
|
30
|
-
|
31
|
-
ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM pg_locks WHERE locktype = 'advisory';").to_i
|
32
|
-
end
|
33
|
-
|
34
|
-
specify 'session locks release after the block executes' do
|
32
|
+
test 'session locks release after the block executes' do
|
35
33
|
Tag.transaction do
|
36
|
-
pg_lock_count.
|
34
|
+
assert_equal(0, @pg_lock_count.call)
|
37
35
|
Tag.with_advisory_lock 'test' do
|
38
|
-
pg_lock_count.
|
36
|
+
assert_equal(1, @pg_lock_count.call)
|
39
37
|
end
|
40
|
-
pg_lock_count.
|
38
|
+
assert_equal(0, @pg_lock_count.call)
|
41
39
|
end
|
42
40
|
end
|
43
41
|
|
44
|
-
|
42
|
+
test 'session locks release when transaction fails inside block' do
|
45
43
|
Tag.transaction do
|
46
|
-
pg_lock_count.
|
44
|
+
assert_equal(0, @pg_lock_count.call)
|
47
45
|
|
48
|
-
exception =
|
46
|
+
exception = assert_raises(ActiveRecord::StatementInvalid) do
|
49
47
|
Tag.with_advisory_lock 'test' do
|
50
48
|
Tag.connection.execute 'SELECT 1/0;'
|
51
49
|
end
|
52
|
-
|
53
|
-
exception.message.must_include 'division by zero'
|
50
|
+
end
|
54
51
|
|
55
|
-
|
52
|
+
assert_match(/#{Regexp.escape('division by zero')}/, exception.message)
|
53
|
+
assert_equal(0, @pg_lock_count.call)
|
56
54
|
end
|
57
55
|
end
|
58
56
|
|
59
|
-
|
57
|
+
test 'transaction level locks hold until the transaction completes' do
|
60
58
|
Tag.transaction do
|
61
|
-
pg_lock_count.
|
59
|
+
assert_equal(0, @pg_lock_count.call)
|
62
60
|
Tag.with_advisory_lock 'test', transaction: true do
|
63
|
-
pg_lock_count.
|
61
|
+
assert_equal(1, @pg_lock_count.call)
|
64
62
|
end
|
65
|
-
pg_lock_count.
|
63
|
+
assert_equal(1, @pg_lock_count.call)
|
66
64
|
end
|
67
|
-
pg_lock_count.
|
65
|
+
assert_equal(0, @pg_lock_count.call)
|
68
66
|
end
|
69
67
|
end
|
70
68
|
end
|
data/with_advisory_lock.gemspec
CHANGED
@@ -1,29 +1,30 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require 'with_advisory_lock/version'
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
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 = { "rubyspecs_mfa_required" => "true" }
|
20
|
+
spec.required_ruby_version = '>= 2.7.0'
|
21
|
+
spec.metadata["yard.run"] = "yri"
|
21
22
|
|
23
|
+
spec.add_runtime_dependency 'activerecord', '>= 6.1'
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
gem.add_development_dependency 'appraisal'
|
25
|
+
spec.add_development_dependency 'appraisal'
|
26
|
+
spec.add_development_dependency 'maxitest'
|
27
|
+
spec.add_development_dependency 'minitest-reporters'
|
28
|
+
spec.add_development_dependency 'mocha'
|
29
|
+
spec.add_development_dependency 'yard'
|
29
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: with_advisory_lock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew McEachen
|
8
|
-
|
8
|
+
- Abdelkader Boudih
|
9
|
+
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2023-10-29 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: activerecord
|
@@ -16,30 +17,16 @@ dependencies:
|
|
16
17
|
requirements:
|
17
18
|
- - ">="
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
+
version: '6.1'
|
20
21
|
type: :runtime
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
25
|
- - ">="
|
25
26
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
27
|
+
version: '6.1'
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: minitest
|
29
|
+
name: appraisal
|
43
30
|
requirement: !ruby/object:Gem::Requirement
|
44
31
|
requirements:
|
45
32
|
- - ">="
|
@@ -53,7 +40,7 @@ dependencies:
|
|
53
40
|
- !ruby/object:Gem::Version
|
54
41
|
version: '0'
|
55
42
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
43
|
+
name: maxitest
|
57
44
|
requirement: !ruby/object:Gem::Requirement
|
58
45
|
requirements:
|
59
46
|
- - ">="
|
@@ -95,7 +82,7 @@ dependencies:
|
|
95
82
|
- !ruby/object:Gem::Version
|
96
83
|
version: '0'
|
97
84
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
85
|
+
name: yard
|
99
86
|
requirement: !ruby/object:Gem::Requirement
|
100
87
|
requirements:
|
101
88
|
- - ">="
|
@@ -111,52 +98,50 @@ dependencies:
|
|
111
98
|
description: Advisory locking for ActiveRecord
|
112
99
|
email:
|
113
100
|
- matthew+github@mceachen.org
|
101
|
+
- terminale@gmail.com
|
114
102
|
executables: []
|
115
103
|
extensions: []
|
116
104
|
extra_rdoc_files: []
|
117
105
|
files:
|
106
|
+
- ".github/workflows/ci.yml"
|
118
107
|
- ".gitignore"
|
119
108
|
- ".tool-versions"
|
120
|
-
- ".travis.yml"
|
121
109
|
- Appraisals
|
122
110
|
- CHANGELOG.md
|
123
111
|
- Gemfile
|
124
112
|
- LICENSE.txt
|
125
113
|
- README.md
|
126
114
|
- Rakefile
|
127
|
-
- gemfiles/
|
128
|
-
- gemfiles/
|
129
|
-
- gemfiles/
|
130
|
-
- gemfiles/activerecord_5.2.gemfile
|
131
|
-
- gemfiles/activerecord_6.0.gemfile
|
115
|
+
- gemfiles/activerecord_6.1.gemfile
|
116
|
+
- gemfiles/activerecord_7.0.gemfile
|
117
|
+
- gemfiles/activerecord_7.1.gemfile
|
132
118
|
- lib/with_advisory_lock.rb
|
133
119
|
- lib/with_advisory_lock/base.rb
|
134
120
|
- lib/with_advisory_lock/concern.rb
|
135
121
|
- lib/with_advisory_lock/database_adapter_support.rb
|
122
|
+
- lib/with_advisory_lock/failed_to_acquire_lock.rb
|
136
123
|
- lib/with_advisory_lock/flock.rb
|
137
124
|
- 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
125
|
- lib/with_advisory_lock/postgresql.rb
|
141
126
|
- lib/with_advisory_lock/version.rb
|
142
127
|
- test/concern_test.rb
|
143
|
-
- test/database.yml
|
144
128
|
- test/lock_test.rb
|
145
|
-
- test/minitest_helper.rb
|
146
129
|
- test/nesting_test.rb
|
147
130
|
- test/options_test.rb
|
148
131
|
- test/parallelism_test.rb
|
149
132
|
- test/shared_test.rb
|
133
|
+
- test/test_helper.rb
|
150
134
|
- test/test_models.rb
|
151
135
|
- test/thread_test.rb
|
152
136
|
- test/transaction_test.rb
|
153
|
-
- tests.sh
|
154
137
|
- with_advisory_lock.gemspec
|
155
|
-
homepage: https://github.com/
|
138
|
+
homepage: https://github.com/ClosureTree/with_advisory_lock
|
156
139
|
licenses:
|
157
140
|
- MIT
|
158
|
-
metadata:
|
159
|
-
|
141
|
+
metadata:
|
142
|
+
rubyspecs_mfa_required: 'true'
|
143
|
+
yard.run: yri
|
144
|
+
post_install_message:
|
160
145
|
rdoc_options: []
|
161
146
|
require_paths:
|
162
147
|
- lib
|
@@ -164,26 +149,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
164
149
|
requirements:
|
165
150
|
- - ">="
|
166
151
|
- !ruby/object:Gem::Version
|
167
|
-
version: 2.
|
152
|
+
version: 2.7.0
|
168
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
154
|
requirements:
|
170
155
|
- - ">="
|
171
156
|
- !ruby/object:Gem::Version
|
172
157
|
version: '0'
|
173
158
|
requirements: []
|
174
|
-
rubygems_version: 3.
|
175
|
-
signing_key:
|
159
|
+
rubygems_version: 3.4.12
|
160
|
+
signing_key:
|
176
161
|
specification_version: 4
|
177
162
|
summary: Advisory locking for ActiveRecord
|
178
163
|
test_files:
|
179
164
|
- test/concern_test.rb
|
180
|
-
- test/database.yml
|
181
165
|
- test/lock_test.rb
|
182
|
-
- test/minitest_helper.rb
|
183
166
|
- test/nesting_test.rb
|
184
167
|
- test/options_test.rb
|
185
168
|
- test/parallelism_test.rb
|
186
169
|
- test/shared_test.rb
|
170
|
+
- test/test_helper.rb
|
187
171
|
- test/test_models.rb
|
188
172
|
- test/thread_test.rb
|
189
173
|
- test/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
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "activerecord", "~> 4.2.0"
|
6
|
-
|
7
|
-
platforms :ruby do
|
8
|
-
gem "mysql2", "< 0.5"
|
9
|
-
gem "pg", "~> 0.21"
|
10
|
-
gem "sqlite3", "~> 1.3.6"
|
11
|
-
end
|
12
|
-
|
13
|
-
platforms :jruby do
|
14
|
-
gem "activerecord-jdbcmysql-adapter"
|
15
|
-
gem "activerecord-jdbcpostgresql-adapter"
|
16
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
17
|
-
end
|
18
|
-
|
19
|
-
gemspec path: "../"
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "activerecord", "~> 5.0.0"
|
6
|
-
|
7
|
-
platforms :ruby do
|
8
|
-
gem "mysql2"
|
9
|
-
gem "pg"
|
10
|
-
gem "sqlite3", "~> 1.3.6"
|
11
|
-
end
|
12
|
-
|
13
|
-
platforms :jruby do
|
14
|
-
gem "activerecord-jdbcmysql-adapter"
|
15
|
-
gem "activerecord-jdbcpostgresql-adapter"
|
16
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
17
|
-
end
|
18
|
-
|
19
|
-
gemspec path: "../"
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "activerecord", "~> 5.1.0"
|
6
|
-
|
7
|
-
platforms :ruby do
|
8
|
-
gem "mysql2"
|
9
|
-
gem "pg"
|
10
|
-
gem "sqlite3", "~> 1.3.6"
|
11
|
-
end
|
12
|
-
|
13
|
-
platforms :jruby do
|
14
|
-
gem "activerecord-jdbcmysql-adapter"
|
15
|
-
gem "activerecord-jdbcpostgresql-adapter"
|
16
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
17
|
-
end
|
18
|
-
|
19
|
-
gemspec path: "../"
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module WithAdvisoryLock
|
2
|
-
# For MySQL < 5.7.5 that does not support nested locks
|
3
|
-
class MySQLNoNesting < MySQL
|
4
|
-
# See http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock
|
5
|
-
def try_lock
|
6
|
-
unless lock_stack.empty?
|
7
|
-
raise NestedAdvisoryLockError.new(
|
8
|
-
"MySQL < 5.7.5 doesn't support nested Advisory Locks",
|
9
|
-
lock_stack.dup
|
10
|
-
)
|
11
|
-
end
|
12
|
-
super
|
13
|
-
end
|
14
|
-
|
15
|
-
# MySQL doesn't support nested locks:
|
16
|
-
def already_locked?
|
17
|
-
lock_stack.last == lock_stack_item
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module WithAdvisoryLock
|
2
|
-
class NestedAdvisoryLockError < StandardError
|
3
|
-
attr_accessor :lock_stack
|
4
|
-
|
5
|
-
def initialize(msg = nil, lock_stack = nil)
|
6
|
-
super(msg)
|
7
|
-
@lock_stack = lock_stack
|
8
|
-
end
|
9
|
-
|
10
|
-
def to_s
|
11
|
-
super + (lock_stack ? ": lock stack = #{lock_stack}" : '')
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
data/test/database.yml
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
sqlite:
|
2
|
-
adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3
|
3
|
-
database: test/sqlite.db
|
4
|
-
timeout: 500
|
5
|
-
pool: 50
|
6
|
-
postgresql:
|
7
|
-
adapter: postgresql
|
8
|
-
username: postgres
|
9
|
-
database: with_advisory_lock_test
|
10
|
-
min_messages: ERROR
|
11
|
-
pool: 50
|
12
|
-
mysql:
|
13
|
-
adapter: mysql2
|
14
|
-
host: localhost
|
15
|
-
username: root
|
16
|
-
database: with_advisory_lock_test
|
17
|
-
pool: 50
|
data/test/minitest_helper.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'erb'
|
2
|
-
require 'active_record'
|
3
|
-
require 'with_advisory_lock'
|
4
|
-
require 'tmpdir'
|
5
|
-
require 'securerandom'
|
6
|
-
|
7
|
-
def env_db
|
8
|
-
(ENV['DB'] || :mysql).to_sym
|
9
|
-
end
|
10
|
-
|
11
|
-
db_config = File.expand_path('database.yml', File.dirname(__FILE__))
|
12
|
-
ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(db_config)).result)
|
13
|
-
|
14
|
-
ENV['WITH_ADVISORY_LOCK_PREFIX'] ||= SecureRandom.hex
|
15
|
-
|
16
|
-
ActiveRecord::Base.establish_connection(env_db)
|
17
|
-
ActiveRecord::Migration.verbose = false
|
18
|
-
|
19
|
-
require 'test_models'
|
20
|
-
begin
|
21
|
-
require 'minitest'
|
22
|
-
rescue LoadError
|
23
|
-
puts 'Failed to load the minitest gem; built-in version will be used.'
|
24
|
-
end
|
25
|
-
require 'minitest/autorun'
|
26
|
-
require 'minitest/great_expectations'
|
27
|
-
require 'mocha/setup'
|
28
|
-
|
29
|
-
class MiniTest::Spec
|
30
|
-
before do
|
31
|
-
ENV['FLOCK_DIR'] = Dir.mktmpdir
|
32
|
-
Tag.delete_all
|
33
|
-
TagAudit.delete_all
|
34
|
-
Label.delete_all
|
35
|
-
end
|
36
|
-
after do
|
37
|
-
FileUtils.remove_entry_secure ENV['FLOCK_DIR']
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|