db_lock 0.8.0 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/db_lock/lock.rb +51 -0
- data/lib/db_lock.rb +1 -38
- metadata +35 -19
- data/config/database_mssql_example.yml +0 -17
- data/config/database_mysql_example.yml +0 -16
- data/lib/db_lock/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3bf2cc97847ee6ffd808862521722c813feaddd2c901b3d7ae2f3048b5f110c6
|
4
|
+
data.tar.gz: a1d6c63848525ac3c5525859ae6ab8de36b4207f316235367bb048ea4d056a25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d86fd46f20a9e2395d5c9c933cc72de655b9639f310ace64d73c1d840eaf3c0ac8e0586cf7eca419aeb093c50aee1856d81df2a08d56bebbc8be8274ae150b2
|
7
|
+
data.tar.gz: 50bbbba20692ca761eecbd696abd5bd942dd8b61db07f4c86687f0adc7a284c4d35753e4f2e07fe53eecf1fcda0db47486125bc3aebe85891a32beb9c8e50eb1
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# DBLock
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/db_lock.svg)](https://badge.fury.io/rb/db_lock)
|
4
|
-
[![
|
4
|
+
[![Tests](https://github.com/mkon/db_lock/actions/workflows/test.yml/badge.svg)](https://github.com/mkon/db_lock/actions/workflows/test.yml)
|
5
5
|
|
6
6
|
Gem to obtain and release manual db locks. This can be utilized for example to make sure that certain rake tasks do not run in parallel on the same database (for example when cron jobs run for too long or are accidentally started multiple times). Currently only supports:
|
7
7
|
|
data/lib/db_lock/lock.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module DBLock
|
4
|
+
module Lock
|
5
|
+
extend self
|
6
|
+
|
7
|
+
# rubocop:disable Metrics/AbcSize
|
8
|
+
def get(name, timeout = 0)
|
9
|
+
timeout = timeout.to_f # catches nil
|
10
|
+
timeout = 0 if timeout.negative?
|
11
|
+
|
12
|
+
raise "Invalid lock name: #{name.inspect}" if name.empty?
|
13
|
+
raise AlreadyLocked, 'Already lock in progress' if locked?
|
14
|
+
|
15
|
+
name = generate_lock_name(name)
|
16
|
+
|
17
|
+
if Adapter.lock(name, timeout)
|
18
|
+
@locked = true
|
19
|
+
yield
|
20
|
+
else
|
21
|
+
raise AlreadyLocked, "Unable to obtain lock '#{name}' within #{timeout} seconds" unless locked?
|
22
|
+
end
|
23
|
+
ensure
|
24
|
+
Adapter.release(name) if locked?
|
25
|
+
@locked = false
|
26
|
+
end
|
27
|
+
# rubocop:enable Metrics/AbcSize
|
28
|
+
|
29
|
+
def locked?
|
30
|
+
@locked ||= false
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def generate_lock_name(name)
|
36
|
+
name = "#{rails_app_name}.#{Rails.env}#{name}" if name[0] == '.' && defined? Rails
|
37
|
+
# reduce lock names of > 64 chars in size
|
38
|
+
# MySQL 5.7 only supports 64 chars max, there might be similar limitations elsewhere
|
39
|
+
name = "#{name.chars.first(15).join}-#{Digest::MD5.hexdigest(name)}-#{name.chars.last(15).join}" if name.length > 64
|
40
|
+
name
|
41
|
+
end
|
42
|
+
|
43
|
+
def rails_app_name
|
44
|
+
if Gem::Version.new(Rails.version) >= Gem::Version.new('6.0.0')
|
45
|
+
Rails.application.class.module_parent_name
|
46
|
+
else
|
47
|
+
Rails.application.class.parent_name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/db_lock.rb
CHANGED
@@ -4,6 +4,7 @@ module DBLock
|
|
4
4
|
extend self
|
5
5
|
|
6
6
|
autoload :Adapter, 'db_lock/adapter'
|
7
|
+
autoload :Lock, 'db_lock/lock'
|
7
8
|
|
8
9
|
class AlreadyLocked < StandardError; end
|
9
10
|
|
@@ -13,42 +14,4 @@ module DBLock
|
|
13
14
|
# this must be an active record base object or subclass
|
14
15
|
@db_handler || ActiveRecord::Base
|
15
16
|
end
|
16
|
-
|
17
|
-
module Lock
|
18
|
-
extend self
|
19
|
-
def get(name, timeout = 0)
|
20
|
-
timeout = timeout.to_f # catches nil
|
21
|
-
timeout = 0 if timeout.negative?
|
22
|
-
raise "Invalid lock name: #{name.inspect}" if name.empty?
|
23
|
-
raise AlreadyLocked, 'Already lock in progress' if locked?
|
24
|
-
|
25
|
-
name = generate_lock_name(name)
|
26
|
-
|
27
|
-
if Adapter.lock(name, timeout)
|
28
|
-
@locked = true
|
29
|
-
yield
|
30
|
-
else
|
31
|
-
raise AlreadyLocked, "Unable to obtain lock '#{name}' within #{timeout} seconds" unless locked?
|
32
|
-
end
|
33
|
-
ensure
|
34
|
-
Adapter.release(name) if locked?
|
35
|
-
@locked = false
|
36
|
-
end
|
37
|
-
|
38
|
-
def locked?
|
39
|
-
@locked ||= false
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def generate_lock_name(name)
|
45
|
-
name = "#{Rails.application.class.parent_name}.#{Rails.env}#{name}" if name[0] == '.' && defined? Rails
|
46
|
-
# reduce lock names of > 64 chars in size
|
47
|
-
# MySQL 5.7 only supports 64 chars max, there might be similar limitations elsewhere
|
48
|
-
if name.length > 64
|
49
|
-
name = "#{name.chars.first(15).join}-#{Digest::MD5.hexdigest(name)}-#{name.chars.last(15).join}"
|
50
|
-
end
|
51
|
-
name
|
52
|
-
end
|
53
|
-
end
|
54
17
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: db_lock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mkon
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '6.1'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '7'
|
22
|
+
version: '7.1'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '6.1'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '7'
|
32
|
+
version: '7.1'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rspec
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,28 +50,42 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - '='
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: 1.29.1
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - '='
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
60
|
+
version: 1.29.1
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: rubocop-rspec
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
65
|
- - '='
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version:
|
67
|
+
version: 2.11.1
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
72
|
- - '='
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
74
|
+
version: 2.11.1
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: simplecov
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
75
89
|
description: Obtain manual db locks to guard blocks of code from parallel execution.Currently
|
76
90
|
only supports mysql and ms-sql-server.
|
77
91
|
email:
|
@@ -82,19 +96,18 @@ extra_rdoc_files: []
|
|
82
96
|
files:
|
83
97
|
- MIT-LICENSE
|
84
98
|
- README.md
|
85
|
-
- config/database_mssql_example.yml
|
86
|
-
- config/database_mysql_example.yml
|
87
99
|
- lib/db_lock.rb
|
88
100
|
- lib/db_lock/adapter.rb
|
89
101
|
- lib/db_lock/adapter/base.rb
|
90
102
|
- lib/db_lock/adapter/mysql.rb
|
91
103
|
- lib/db_lock/adapter/sqlserver.rb
|
92
|
-
- lib/db_lock/
|
104
|
+
- lib/db_lock/lock.rb
|
93
105
|
homepage: https://github.com/mkon/db_lock
|
94
106
|
licenses:
|
95
107
|
- MIT
|
96
|
-
metadata:
|
97
|
-
|
108
|
+
metadata:
|
109
|
+
rubygems_mfa_required: 'true'
|
110
|
+
post_install_message:
|
98
111
|
rdoc_options: []
|
99
112
|
require_paths:
|
100
113
|
- lib
|
@@ -102,15 +115,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
102
115
|
requirements:
|
103
116
|
- - ">="
|
104
117
|
- !ruby/object:Gem::Version
|
105
|
-
version: '
|
118
|
+
version: '2.7'
|
119
|
+
- - "<"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '4'
|
106
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
123
|
requirements:
|
108
124
|
- - ">="
|
109
125
|
- !ruby/object:Gem::Version
|
110
126
|
version: '0'
|
111
127
|
requirements: []
|
112
|
-
rubygems_version: 3.
|
113
|
-
signing_key:
|
128
|
+
rubygems_version: 3.3.7
|
129
|
+
signing_key:
|
114
130
|
specification_version: 4
|
115
131
|
summary: Obtain manual db/mysql locks
|
116
132
|
test_files: []
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# rename/copy to database.yml and adjust to your local settings
|
2
|
-
|
3
|
-
base: &base
|
4
|
-
adapter: sqlserver
|
5
|
-
host: 192.168.99.100
|
6
|
-
port: 50012
|
7
|
-
encoding: utf8
|
8
|
-
reconnect: false
|
9
|
-
pool: 5
|
10
|
-
username: root
|
11
|
-
password: dummy
|
12
|
-
|
13
|
-
development:
|
14
|
-
<<: *base
|
15
|
-
|
16
|
-
test:
|
17
|
-
<<: *base
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# rename/copy to database.yml and adjust to your local settings
|
2
|
-
|
3
|
-
base: &base
|
4
|
-
adapter: mysql2
|
5
|
-
host: localhost
|
6
|
-
encoding: utf8
|
7
|
-
reconnect: false
|
8
|
-
pool: 5
|
9
|
-
username: root
|
10
|
-
password: dummy
|
11
|
-
|
12
|
-
development:
|
13
|
-
<<: *base
|
14
|
-
|
15
|
-
test:
|
16
|
-
<<: *base
|
data/lib/db_lock/version.rb
DELETED