active_record_mutex 3.2.0 → 3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34e4fb422fbe0336eee934df7fdeb49843c4b0335fe4222db9d8df1728b7d477
4
- data.tar.gz: c3dc8c6fe86409160ded37ed5941cef3033d03b82e60c630c950ade50fc1d901
3
+ metadata.gz: cf654fec02b6d69bd364a26520e1ee2308988193b2938ff514e61bb202661a42
4
+ data.tar.gz: f4cdcb9803f4db880ccda320bef2ca58c680be9365ca696069afd7c1781968c3
5
5
  SHA512:
6
- metadata.gz: bd1437072b603f1dd5641d70970fe3bd2a24e77862a88d035222b4b1c0c360eb99ce14a573be87fc2e331e85955283262380be09c709e3bad936944a36b6615a
7
- data.tar.gz: 2f4528e9a7d63ce3e2f9584f0b0099c783b07bf518174fd50c107237e0ad994fed77519f408ef27daa3aa752d3df1452fdc7a0139a312c21fe6d708d77cc5f0c
6
+ metadata.gz: bb44138a04d61609b26bd89dcc4ab663231768d4c9763b215c42161974705ed65a0bd2aa1fd911b2b0dabf2f5792ea842c93366d6b4432bbbf55fd317cf4bb7d
7
+ data.tar.gz: c0bb4dfdbd775a767690881bf3e2973caf70aa454c765d7ef4294b5853bdd05af09e7c9e712deece3d3b1d3b604a5aebe3e211765363eb19cf966015af0bc4ae
data/CHANGES.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-01-02 v3.3.0
4
+
5
+ - Updated `all_images` development dependency from version **0.6** to
6
+ **0.11.2** in `active_record_mutex.gemspec`
7
+ - Enabled MariaDB TLS peer verification disable option via environment variable
8
+ in `.all_images.yml`
9
+ - Added `yaml-dev` and `openssl-dev` packages to Alpine package installation in
10
+ `.all_images.yml`
11
+ - Updated Ruby gem system and installed `bundler` and `gem_hadar` using `gem
12
+ update --system` and `gem install`
13
+ - Replaced `bundle install --full-index` with `bundle update --all` and `bundle
14
+ install --jobs=$(getconf _NPROCESSORS_ONLN)`
15
+ - Added `ruby:4.0-alpine` image configuration to the test suite
16
+ - Updated `s.date` from **2024-10-16** to **1980-01-02**
17
+ - Updated `s.rubygems_version` from **3.5.18** to **4.0.2**
18
+ - Updated `gem_hadar` development dependency from version **~> 1.19** to **>=
19
+ 2.16.3**
20
+ - Added `changelog` block in `Rakefile` to specify `CHANGES.md` as the
21
+ changelog filename
22
+ - Removed binary detection config in file discovery
23
+ - Updated Docker image for Ruby **3.4**
24
+ - Added support for Ruby **3.4**-alpine images
25
+ - Removed support for Ruby **3.2**-alpine images
26
+ - Added fenced codeblocks for syntax highlighter hints in README.md
27
+
28
+ ## 2024-10-16 v3.2.1
29
+
30
+ * Refactor DatabaseMutex implementation:
31
+ * Change `@name` and `mutex.name` to downcase and freeze values
32
+ * Update tests to reflect new behavior
33
+
34
+ ## 2024-10-16 v3.2.0
35
+
36
+ * DatabaseMutex improvements:
37
+ * Improved lock name generation in `lock_name` method.
38
+ * Modified SQL queries to use `lock_name` instead of `internal_name`.
39
+ * Added `lock_exists?` and `test_all_mutexes` methods for testing mutex
40
+ creation and querying.
41
+
3
42
  ## 2024-10-16 v3.1.0
4
43
 
5
44
  * Changes for **3.1.0**:
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # ActiveRecord::Mutex
1
+ # ActiveRecord Database Mutex
2
2
 
3
3
  ## Description
4
4
 
@@ -10,11 +10,16 @@ ruby processes (also on different hosts) via the connected database.
10
10
 
11
11
  You can use rubygems to fetch the gem and install it for you:
12
12
 
13
- # gem install active_record_mutex
13
+ ```bash
14
+ gem install active_record_mutex
15
+ ```
14
16
 
15
17
  You can also put this line into your Gemfile
16
18
 
17
- gem 'active_record_mutex'
19
+ ```ruby
20
+ # Gemfile
21
+ gem 'active_record_mutex'
22
+ ```
18
23
 
19
24
  ## Usage
20
25
 
@@ -22,25 +27,31 @@ You can also put this line into your Gemfile
22
27
 
23
28
  To synchronize on a specific ActiveRecord instance you can do this:
24
29
 
25
- class Foo < ActiveRecord::Base
26
- end
30
+ ```ruby
31
+ class Foo < ActiveRecord::Base
32
+ end
27
33
 
28
- foo = Foo.find(666)
29
- foo.mutex.synchronize do
30
- # Critical section of code here
31
- end
34
+ foo = Foo.find(666)
35
+ foo.mutex.synchronize do
36
+ # Critical section of code here
37
+ end
38
+ ```
32
39
 
33
40
  If you want more control over the mutex and/or give it a special name you can
34
41
  create Mutex instance like this:
35
42
 
36
- my_mutex = ActiveRecord::DatabaseMutex.for('my_mutex')
43
+ ```ruby
44
+ my_mutex = ActiveRecord::DatabaseMutex.for('my_mutex')
45
+ ``````
37
46
 
38
47
  Now you can send all messages directly to the Mutex instance or use the custom
39
48
  mutex instance to `synchronize` method calls or other operations:
40
49
 
41
- my_mutex.synchronize do
42
- # Critical section of code here
43
- end
50
+ ```ruby
51
+ my_mutex.synchronize do
52
+ # Critical section of code here
53
+ end
54
+ ```
44
55
 
45
56
  ### Low-Level Demonstration: Multiple Process Example
46
57
 
@@ -51,50 +62,54 @@ rather to illustrate the underlying behavior.
51
62
  If two processes are connected to the same database, configured via e.g.
52
63
  `DATABASE_URL=mysql2://root@127.0.0.1:3336/test` and this is process 1:
53
64
 
54
- # process1.rb
55
-
56
- mutex = ActiveRecord::DatabaseMutex.for('my_mutex')
65
+ ```ruby
66
+ # process1.rb
67
+
68
+ mutex = ActiveRecord::DatabaseMutex.for('my_mutex')
57
69
 
58
- lock_result1 = mutex.lock(timeout: 5)
59
- puts "Process 1: Lock acquired (first): #{lock_result1}"
70
+ lock_result1 = mutex.lock(timeout: 5)
71
+ puts "Process 1: Lock acquired (first): #{lock_result1}"
60
72
 
61
- puts "Process 1: Waiting for 10s"
62
- sleep(10)
73
+ puts "Process 1: Waiting for 10s"
74
+ sleep(10)
63
75
 
64
- lock_result2 = mutex.lock(timeout: 5)
65
- puts "Process 1: Lock acquired (second): #{lock_result2}"
76
+ lock_result2 = mutex.lock(timeout: 5)
77
+ puts "Process 1: Lock acquired (second): #{lock_result2}"
66
78
 
67
- mutex.unlock # first
68
- mutex.unlock # second
79
+ mutex.unlock # first
80
+ mutex.unlock # second
69
81
 
70
- puts "Process 1: Unlocked the mutex twice"
82
+ puts "Process 1: Unlocked the mutex twice"
71
83
 
72
- puts "Process 1: Waiting for 10s"
73
- sleep(10)
84
+ puts "Process 1: Waiting for 10s"
85
+ sleep(10)
74
86
 
75
- puts "Process 1: Exiting"
87
+ puts "Process 1: Exiting"
88
+ ```
76
89
 
77
90
  and this process 2:
78
91
 
79
- # process2.rb
80
-
81
- mutex = ActiveRecord::DatabaseMutex.for('my_mutex')
92
+ ```ruby
93
+ # process2.rb
94
+
95
+ mutex = ActiveRecord::DatabaseMutex.for('my_mutex')
82
96
 
83
- begin
84
- lock_result3 = mutex.lock(timeout: 5)
85
- puts "Process 2: Lock acquired (first): #{lock_result3}"
86
- rescue ActiveRecord::DatabaseMutex::MutexLocked
87
- puts "Process 2: Mutex locked by another process, waiting..."
88
- end
97
+ begin
98
+ lock_result3 = mutex.lock(timeout: 5)
99
+ puts "Process 2: Lock acquired (first): #{lock_result3}"
100
+ rescue ActiveRecord::DatabaseMutex::MutexLocked
101
+ puts "Process 2: Mutex locked by another process, waiting..."
102
+ end
89
103
 
90
- puts "Process 2: Waiting for 10s"
91
- sleep(10)
104
+ puts "Process 2: Waiting for 10s"
105
+ sleep(10)
92
106
 
93
- puts "Process 2: Trying to lock again"
94
- lock_result4 = mutex.lock(timeout: 5)
95
- puts "Process 2: Lock acquired (second): #{lock_result4}"
107
+ puts "Process 2: Trying to lock again"
108
+ lock_result4 = mutex.lock(timeout: 5)
109
+ puts "Process 2: Lock acquired (second): #{lock_result4}"
96
110
 
97
- puts "Process 2: Exiting"
111
+ puts "Process 2: Exiting"
112
+ ```
98
113
 
99
114
  Running these processes in parallel will output the following:
100
115
 
@@ -120,15 +135,21 @@ files, `.envrc` (`direnv allow`) and `docker-compose.yml`
120
135
  First start mysql in docker via `docker compose up -d` and configure your
121
136
  environment via `direnv allow` as before and then run
122
137
 
123
- rake test
138
+ ```bash
139
+ rake test
140
+ ```
124
141
 
125
142
  or with coverage:
126
143
 
127
- rake test START_SIMPLECOV=1
144
+ ```bash
145
+ rake test START_SIMPLECOV=1
146
+ ```
128
147
 
129
148
  To test for different ruby versions in docker, run:
130
149
 
131
- all_images
150
+ ```bash
151
+ all_images
152
+ ```
132
153
 
133
154
  ## Download
134
155
 
data/Rakefile CHANGED
@@ -19,10 +19,14 @@ GemHadar do
19
19
  readme 'README.md'
20
20
  licenses << 'GPL-2'
21
21
 
22
+ changelog do
23
+ filename 'CHANGES.md'
24
+ end
25
+
22
26
  dependency 'mysql2', '~> 0.3'
23
27
  dependency 'activerecord', '>= 4.0'
24
28
  dependency 'ostruct', '~> 0.6'
25
- development_dependency 'all_images', '~> 0.6'
29
+ development_dependency 'all_images', '>= 0.11.2'
26
30
  development_dependency 'test-unit', '~> 3.0'
27
31
  development_dependency 'debug'
28
32
  development_dependency 'simplecov'
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: active_record_mutex 3.2.0 ruby lib
2
+ # stub: active_record_mutex 3.3.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "active_record_mutex".freeze
6
- s.version = "3.2.0".freeze
6
+ s.version = "3.3.0".freeze
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
10
10
  s.authors = ["Florian Frank".freeze]
11
- s.date = "2024-10-16"
11
+ s.date = "1980-01-02"
12
12
  s.description = "Mutex that can be used to synchronise ruby processes via an ActiveRecord datababase connection. (Only Mysql is supported at the moment.)".freeze
13
13
  s.email = "flori@ping.de".freeze
14
14
  s.extra_rdoc_files = ["README.md".freeze, "lib/active_record/database_mutex.rb".freeze, "lib/active_record/database_mutex/implementation.rb".freeze, "lib/active_record/database_mutex/version.rb".freeze, "lib/active_record/mutex.rb".freeze, "lib/active_record_mutex.rb".freeze]
@@ -16,14 +16,14 @@ Gem::Specification.new do |s|
16
16
  s.homepage = "http://github.com/flori/active_record_mutex".freeze
17
17
  s.licenses = ["GPL-2".freeze]
18
18
  s.rdoc_options = ["--title".freeze, "ActiveRecordMutex - Implementation of a Mutex for Active Record".freeze, "--main".freeze, "README.md".freeze]
19
- s.rubygems_version = "3.5.18".freeze
19
+ s.rubygems_version = "4.0.2".freeze
20
20
  s.summary = "Implementation of a Mutex for Active Record".freeze
21
21
  s.test_files = ["test/database_mutex_test.rb".freeze, "test/test_helper.rb".freeze]
22
22
 
23
23
  s.specification_version = 4
24
24
 
25
- s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.19".freeze])
26
- s.add_development_dependency(%q<all_images>.freeze, ["~> 0.6".freeze])
25
+ s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.16.3".freeze])
26
+ s.add_development_dependency(%q<all_images>.freeze, [">= 0.11.2".freeze])
27
27
  s.add_development_dependency(%q<test-unit>.freeze, ["~> 3.0".freeze])
28
28
  s.add_development_dependency(%q<debug>.freeze, [">= 0".freeze])
29
29
  s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
@@ -20,9 +20,10 @@ module ActiveRecord
20
20
  #
21
21
  # @raise [ ArgumentError ] if no **name** option is provided in the options hash.
22
22
  def initialize(opts = {})
23
- @name = opts[:name].to_s
23
+ @name = opts[:name].to_s.downcase
24
24
  @name.size != 0 or raise ArgumentError, "mutex requires a nonempty :name argument"
25
- internal_name # create/check internal_name
25
+ @name.freeze
26
+ lock_name # create/check internal_name and lock_name
26
27
  end
27
28
 
28
29
  # Returns the name of this mutex as given via the constructor argument.
@@ -35,7 +36,8 @@ module ActiveRecord
35
36
  def internal_name
36
37
  @internal_name and return @internal_name
37
38
  encoded_name = ?$ + Digest::MD5.base64digest([ self.class.name, name ] * ?#).
38
- delete('^A-Za-z0-9+/').gsub(/[+\/]/, ?+ => ?_, ?/ => ?.)
39
+ delete('^A-Za-z0-9+/').gsub(/[+\/]/, ?+ => ?_, ?/ => ?.).
40
+ downcase.freeze
39
41
  if encoded_name.size <= 64
40
42
  @internal_name = encoded_name
41
43
  else
@@ -50,8 +52,11 @@ module ActiveRecord
50
52
  #
51
53
  # @return [ String ] the generated lock name
52
54
  def lock_name
55
+ @lock_name and return @lock_name
53
56
  prefix_name = name.gsub(/[^[:print:]]/, '')[0, 32]
54
- prefix_name + ?= + internal_name
57
+ @lock_name = prefix_name + ?= + internal_name
58
+ @lock_name.downcase!
59
+ @lock_name.freeze
55
60
  end
56
61
 
57
62
  # The synchronize method attempts to acquire a mutex lock for the given name
@@ -1,6 +1,6 @@
1
1
  module ActiveRecord::DatabaseMutex
2
2
  # ActiveRecord::DatabaseMutex version
3
- VERSION = '3.2.0'
3
+ VERSION = '3.3.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
@@ -25,7 +25,7 @@ class DatabaseMutexTest < Test::Unit::TestCase
25
25
  old, ENV['RAILS_ENV'] = ENV['RAILS_ENV'], nil
26
26
  mutex = Foo.mutex
27
27
  assert_kind_of ActiveRecord::DatabaseMutex::Implementation, mutex
28
- assert_equal Foo.name, mutex.name
28
+ assert_equal Foo.name.downcase, mutex.name
29
29
  ensure
30
30
  ENV['RAILS_ENV'] = old
31
31
  end
@@ -34,7 +34,7 @@ class DatabaseMutexTest < Test::Unit::TestCase
34
34
  old, ENV['RAILS_ENV'] = ENV['RAILS_ENV'], 'test'
35
35
  mutex = Foo.mutex
36
36
  assert_kind_of ActiveRecord::DatabaseMutex::Implementation, mutex
37
- assert_equal "#{Foo.name}@test", mutex.name
37
+ assert_equal "#{Foo.name}@test".downcase, mutex.name
38
38
  ensure
39
39
  ENV['RAILS_ENV'] = old
40
40
  end
@@ -47,7 +47,7 @@ class DatabaseMutexTest < Test::Unit::TestCase
47
47
  assert_equal true, instance.save
48
48
  mutex = instance.mutex
49
49
  assert_kind_of ActiveRecord::DatabaseMutex::Implementation, mutex
50
- assert_equal "#{instance.id}@#{Foo.name}", mutex.name
50
+ assert_equal "#{instance.id}@#{Foo.name}".downcase, mutex.name
51
51
  end
52
52
 
53
53
  def test_factory_method_for
@@ -56,6 +56,7 @@ class DatabaseMutexTest < Test::Unit::TestCase
56
56
  end
57
57
 
58
58
  private def lock_exists?(string)
59
+ string = string.downcase
59
60
  ActiveRecord::Base.all_mutexes.map(&:OBJECT_NAME).any? {
60
61
  _1.include?(string)
61
62
  }
@@ -73,7 +74,7 @@ class DatabaseMutexTest < Test::Unit::TestCase
73
74
 
74
75
  def test_create
75
76
  mutex = Implementation.new(:name => 'Create')
76
- assert_equal 'Create', mutex.name
77
+ assert_equal 'create', mutex.name
77
78
  end
78
79
 
79
80
  def test_lock
@@ -284,11 +285,11 @@ class DatabaseMutexTest < Test::Unit::TestCase
284
285
 
285
286
  def test_internal_name
286
287
  mutex = Implementation.new(:name => (250..255).map(&:chr) * '')
287
- assert_equal '$3i3xQvUrNPGyH6kaIOkiPw', mutex.send(:internal_name)
288
+ assert_equal '$3i3xqvurnpgyh6kaiokipw', mutex.send(:internal_name)
288
289
  end
289
290
 
290
291
  def test_counter_name
291
292
  mutex = Implementation.new(:name => (250..255).map(&:chr) * '')
292
- assert_equal '@$3i3xQvUrNPGyH6kaIOkiPw', mutex.send(:counter)
293
+ assert_equal '@$3i3xqvurnpgyh6kaiokipw', mutex.send(:counter)
293
294
  end
294
295
  end
metadata CHANGED
@@ -1,43 +1,42 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_mutex
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-10-16 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: gem_hadar
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
- - - "~>"
16
+ - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '1.19'
18
+ version: 2.16.3
20
19
  type: :development
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
- - - "~>"
23
+ - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: '1.19'
25
+ version: 2.16.3
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: all_images
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
- - - "~>"
30
+ - - ">="
32
31
  - !ruby/object:Gem::Version
33
- version: '0.6'
32
+ version: 0.11.2
34
33
  type: :development
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
- - - "~>"
37
+ - - ">="
39
38
  - !ruby/object:Gem::Version
40
- version: '0.6'
39
+ version: 0.11.2
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: test-unit
43
42
  requirement: !ruby/object:Gem::Requirement
@@ -156,7 +155,6 @@ homepage: http://github.com/flori/active_record_mutex
156
155
  licenses:
157
156
  - GPL-2
158
157
  metadata: {}
159
- post_install_message:
160
158
  rdoc_options:
161
159
  - "--title"
162
160
  - ActiveRecordMutex - Implementation of a Mutex for Active Record
@@ -175,8 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
173
  - !ruby/object:Gem::Version
176
174
  version: '0'
177
175
  requirements: []
178
- rubygems_version: 3.5.18
179
- signing_key:
176
+ rubygems_version: 4.0.2
180
177
  specification_version: 4
181
178
  summary: Implementation of a Mutex for Active Record
182
179
  test_files: