master_lock 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -1
- data/lib/master_lock/redis_lock.rb +7 -3
- data/lib/master_lock/registry.rb +7 -1
- data/lib/master_lock/version.rb +1 -1
- data/lib/master_lock.rb +18 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ab9ca1ac176e6f632f6c3d71ed4008bec96df23
|
4
|
+
data.tar.gz: 43f2c87012e46141d08990ae8e5ce4badfba36e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f5a952ef00b065ef69563acdb808a2921726229be3ea9c78bf15b6070804ae8d8020f3cea5fd2e27f6ce52ae69d7bc13c4ec1d1a7dc6d9072cee626af4c4a19
|
7
|
+
data.tar.gz: 82d2e7768c6d528d211f53870b06296194b328fb0ce4f703cfdd6e31287a1a8514a73c0f9a0db4776b194b9c32b1f0296d73738b9eeb83b20dfaa89e3548917f
|
data/README.md
CHANGED
@@ -24,7 +24,19 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
## Usage
|
26
26
|
|
27
|
-
|
27
|
+
```ruby
|
28
|
+
def perform_safe_operation
|
29
|
+
MasterLock.synchronize("perform_safe_operation") do
|
30
|
+
# Code executes within locked context
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Call MasterLock.start when your application boots up.
|
35
|
+
# This starts a background thread to prevent locks from expiring.
|
36
|
+
MasterLock.start
|
37
|
+
```
|
38
|
+
|
39
|
+
See [documentation](http://www.rubydoc.info/gems/master_lock) for advanced usage.
|
28
40
|
|
29
41
|
## Development
|
30
42
|
|
@@ -44,7 +44,7 @@ module MasterLock
|
|
44
44
|
def acquire(timeout:)
|
45
45
|
timeout_time = Time.now + timeout
|
46
46
|
loop do
|
47
|
-
locked = redis.set(
|
47
|
+
locked = redis.set(redis_key, owner, nx: true, px: ttl_ms)
|
48
48
|
return true if locked
|
49
49
|
return false if Time.now >= timeout_time
|
50
50
|
sleep(@sleep_interval)
|
@@ -60,7 +60,7 @@ module MasterLock
|
|
60
60
|
result = eval_script(
|
61
61
|
RedisScripts::EXTEND_SCRIPT,
|
62
62
|
RedisScripts::EXTEND_SCRIPT_HASH,
|
63
|
-
keys: [
|
63
|
+
keys: [redis_key],
|
64
64
|
argv: [owner, ttl_ms]
|
65
65
|
)
|
66
66
|
result != 0
|
@@ -74,7 +74,7 @@ module MasterLock
|
|
74
74
|
result = eval_script(
|
75
75
|
RedisScripts::RELEASE_SCRIPT,
|
76
76
|
RedisScripts::RELEASE_SCRIPT_HASH,
|
77
|
-
keys: [
|
77
|
+
keys: [redis_key],
|
78
78
|
argv: [owner]
|
79
79
|
)
|
80
80
|
result != 0
|
@@ -93,5 +93,9 @@ module MasterLock
|
|
93
93
|
redis.eval(script, keys: keys, argv: argv)
|
94
94
|
end
|
95
95
|
end
|
96
|
+
|
97
|
+
def redis_key
|
98
|
+
"#{MasterLock.config.key_prefix}:#{key}"
|
99
|
+
end
|
96
100
|
end
|
97
101
|
end
|
data/lib/master_lock/registry.rb
CHANGED
@@ -69,15 +69,21 @@ module MasterLock
|
|
69
69
|
def extend_lock(registration)
|
70
70
|
registration.mutex.synchronize do
|
71
71
|
time = Time.now
|
72
|
+
lock_key = registration.lock.key
|
72
73
|
if !registration.thread.alive?
|
73
74
|
registration.released = true
|
75
|
+
MasterLock.logger.info(
|
76
|
+
"Releasing lock #{lock_key} after owning thread terminated"
|
77
|
+
)
|
74
78
|
elsif !registration.released &&
|
75
79
|
registration.acquired_at + registration.extend_interval < time
|
80
|
+
lock_key = registration.lock.key
|
76
81
|
if registration.lock.extend
|
77
82
|
registration.acquired_at = time
|
83
|
+
MasterLock.logger.debug("Renewed lease on lock #{lock_key}")
|
78
84
|
else
|
79
85
|
registration.released = true
|
80
|
-
|
86
|
+
MasterLock.logger.warn("Could not renew lease on lock #{lock_key}")
|
81
87
|
end
|
82
88
|
end
|
83
89
|
end
|
data/lib/master_lock/version.rb
CHANGED
data/lib/master_lock.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'master_lock/version'
|
2
2
|
|
3
|
+
require 'logger'
|
3
4
|
require 'socket'
|
4
5
|
|
5
6
|
# MasterLock is a system for interprocess locking. Resources can be locked by a
|
@@ -27,6 +28,7 @@ module MasterLock
|
|
27
28
|
:acquire_timeout,
|
28
29
|
:extend_interval,
|
29
30
|
:hostname,
|
31
|
+
:logger,
|
30
32
|
:key_prefix,
|
31
33
|
:process_id,
|
32
34
|
:redis,
|
@@ -72,7 +74,7 @@ module MasterLock
|
|
72
74
|
|
73
75
|
lock = RedisLock.new(
|
74
76
|
redis: config.redis,
|
75
|
-
key:
|
77
|
+
key: key,
|
76
78
|
ttl: ttl,
|
77
79
|
owner: generate_owner
|
78
80
|
)
|
@@ -82,11 +84,16 @@ module MasterLock
|
|
82
84
|
|
83
85
|
registration =
|
84
86
|
@registry.register(lock, extend_interval)
|
87
|
+
logger.debug("Acquired lock #{key}")
|
85
88
|
begin
|
86
89
|
yield
|
87
90
|
ensure
|
88
91
|
@registry.unregister(registration)
|
89
|
-
lock.release
|
92
|
+
if lock.release
|
93
|
+
logger.debug("Released lock #{key}")
|
94
|
+
else
|
95
|
+
logger.warn("Failed to release lock #{key}")
|
96
|
+
end
|
90
97
|
end
|
91
98
|
end
|
92
99
|
|
@@ -103,6 +110,13 @@ module MasterLock
|
|
103
110
|
end
|
104
111
|
end
|
105
112
|
|
113
|
+
# Get the configured logger.
|
114
|
+
#
|
115
|
+
# @return [Logger]
|
116
|
+
def logger
|
117
|
+
config.logger
|
118
|
+
end
|
119
|
+
|
106
120
|
# @return [Config] MasterLock configuration settings
|
107
121
|
def config
|
108
122
|
if !defined?(@config)
|
@@ -110,6 +124,8 @@ module MasterLock
|
|
110
124
|
@config.acquire_timeout = DEFAULT_ACQUIRE_TIMEOUT
|
111
125
|
@config.extend_interval = DEFAULT_EXTEND_INTERVAL
|
112
126
|
@config.hostname = Socket.gethostname
|
127
|
+
@config.logger = Logger.new(STDOUT)
|
128
|
+
@config.logger.progname = name
|
113
129
|
@config.key_prefix = DEFAULT_KEY_PREFIX
|
114
130
|
@config.process_id = Process.pid
|
115
131
|
@config.sleep_time = DEFAULT_SLEEP_TIME
|
@@ -135,10 +151,6 @@ module MasterLock
|
|
135
151
|
def generate_owner
|
136
152
|
"#{config.hostname}:#{config.process_id}:#{Thread.current.object_id}"
|
137
153
|
end
|
138
|
-
|
139
|
-
def redis_key(key)
|
140
|
-
"#{config.key_prefix}:#{key}"
|
141
|
-
end
|
142
154
|
end
|
143
155
|
end
|
144
156
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: master_lock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Posen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|