unique_thread 0.2.0 → 0.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 +4 -4
- data/lib/unique_thread.rb +31 -18
- data/lib/unique_thread/locksmith.rb +10 -13
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84cdf521ad296d825e220ccea5b2610e70bef0dc
|
4
|
+
data.tar.gz: 07fe1de3059244ae0681c152fd249fdf75568d59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34a8c80ee3e585946fc6c4d662bf0ce1f525a4506880e5f585f081cc47cf68715d14c860060d5c86f7852d154fde9ac7cbbea1fcd4767bf047c0d1e2c3271f58
|
7
|
+
data.tar.gz: 2f7be9c25bfa9f6fded8c7d1fb9507f06790d43b6f784c8bfe41f563c63b8dd0f9a7e313063c0d18a9133fa91eefdc551769dbc8a6cf2cb69702956a190e30c9
|
data/lib/unique_thread.rb
CHANGED
@@ -6,12 +6,36 @@ require_relative 'unique_thread/stopwatch'
|
|
6
6
|
require_relative 'unique_thread/locksmith'
|
7
7
|
|
8
8
|
class UniqueThread
|
9
|
-
|
9
|
+
class << self
|
10
|
+
attr_writer :logger, :redis
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
def logger
|
13
|
+
@logger ||= default_logger
|
14
|
+
end
|
15
|
+
|
16
|
+
def redis
|
17
|
+
@redis ||= Redis.new
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def default_logger
|
23
|
+
case
|
24
|
+
when defined?(Rails) && defined?(Rails::Console)
|
25
|
+
Logger.new('/dev/null')
|
26
|
+
when defined?(Rails)
|
27
|
+
Rails.logger
|
28
|
+
else
|
29
|
+
Logger.new($stdout)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_reader :stopwatch, :locksmith
|
35
|
+
|
36
|
+
def initialize(name, downtime: 30)
|
13
37
|
@stopwatch = Stopwatch.new(downtime: downtime)
|
14
|
-
@locksmith = Locksmith.new(name: name, stopwatch: stopwatch
|
38
|
+
@locksmith = Locksmith.new(name: name, stopwatch: stopwatch)
|
15
39
|
end
|
16
40
|
|
17
41
|
def run(&block)
|
@@ -19,10 +43,10 @@ class UniqueThread
|
|
19
43
|
lock = locksmith.new_lock
|
20
44
|
|
21
45
|
if lock.acquired?
|
22
|
-
logger.info('Lock acquired! Running the unique thread.')
|
46
|
+
self.class.logger.info('Lock acquired! Running the unique thread.')
|
23
47
|
lock.while_held(&block)
|
24
48
|
else
|
25
|
-
logger.debug('Could not acquire the lock. Sleeping until next attempt.')
|
49
|
+
self.class.logger.debug('Could not acquire the lock. Sleeping until next attempt.')
|
26
50
|
stopwatch.sleep_until_next_attempt(lock.locked_until.to_f)
|
27
51
|
end
|
28
52
|
end
|
@@ -30,23 +54,12 @@ class UniqueThread
|
|
30
54
|
|
31
55
|
private
|
32
56
|
|
33
|
-
def self.default_logger
|
34
|
-
case
|
35
|
-
when defined?(Rails) && defined?(Rails::Console)
|
36
|
-
Logger.new('/dev/null')
|
37
|
-
when defined?(Rails)
|
38
|
-
Rails.logger
|
39
|
-
else
|
40
|
-
Logger.new(STDOUT)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
57
|
def safe_infinite_loop
|
45
58
|
Thread.new do
|
46
59
|
begin
|
47
60
|
loop { yield }
|
48
61
|
rescue StandardError => error
|
49
|
-
logger.error(error)
|
62
|
+
self.class.logger.error(error)
|
50
63
|
end
|
51
64
|
end
|
52
65
|
end
|
@@ -2,16 +2,14 @@
|
|
2
2
|
|
3
3
|
class UniqueThread
|
4
4
|
class Locksmith
|
5
|
-
attr_reader :name, :stopwatch
|
5
|
+
attr_reader :name, :stopwatch
|
6
6
|
|
7
|
-
def initialize(name:, stopwatch
|
7
|
+
def initialize(name:, stopwatch:)
|
8
8
|
@name = name
|
9
9
|
@stopwatch = stopwatch
|
10
|
-
@redis = redis
|
11
|
-
@logger = logger
|
12
10
|
|
13
11
|
@lua_scripts = Hash[Dir[File.join(__dir__, 'redis_lua', '*.lua')].map do |lua_file|
|
14
|
-
[File.basename(lua_file, '.lua').to_sym, redis.script(:load, File.read(lua_file))]
|
12
|
+
[File.basename(lua_file, '.lua').to_sym, UniqueThread.redis.script(:load, File.read(lua_file))]
|
15
13
|
end]
|
16
14
|
end
|
17
15
|
|
@@ -34,7 +32,7 @@ class UniqueThread
|
|
34
32
|
attr_reader :lua_scripts
|
35
33
|
|
36
34
|
def lock_from_redis_command(script, *args)
|
37
|
-
redis_result = RedisResult.new(*redis.evalsha(lua_scripts[script], args))
|
35
|
+
redis_result = RedisResult.new(*UniqueThread.redis.evalsha(lua_scripts[script], args))
|
38
36
|
|
39
37
|
klass = if redis_result.lock_acquired?
|
40
38
|
HeldLock
|
@@ -42,20 +40,19 @@ class UniqueThread
|
|
42
40
|
Lock
|
43
41
|
end
|
44
42
|
|
45
|
-
klass.new(redis_result.locked_until, stopwatch, self
|
43
|
+
klass.new(redis_result.locked_until, stopwatch, self)
|
46
44
|
end
|
47
45
|
end
|
48
46
|
|
49
47
|
private
|
50
48
|
|
51
49
|
class Lock
|
52
|
-
attr_reader :locked_until, :stopwatch, :locksmith
|
50
|
+
attr_reader :locked_until, :stopwatch, :locksmith
|
53
51
|
|
54
|
-
def initialize(locked_until, stopwatch, locksmith
|
52
|
+
def initialize(locked_until, stopwatch, locksmith)
|
55
53
|
@locked_until = locked_until
|
56
54
|
@stopwatch = stopwatch
|
57
55
|
@locksmith = locksmith
|
58
|
-
@logger = logger
|
59
56
|
end
|
60
57
|
|
61
58
|
def acquired?
|
@@ -75,12 +72,12 @@ class UniqueThread
|
|
75
72
|
def while_held
|
76
73
|
worker = Thread.new do
|
77
74
|
yield
|
78
|
-
logger.error('The blocked passed is not an infinite loop.')
|
75
|
+
UniqueThread.logger.error('The blocked passed is not an infinite loop.')
|
79
76
|
end
|
80
77
|
|
81
78
|
renew_indefinitely
|
82
79
|
|
83
|
-
logger.info('Lock lost! Killing the unique thread.')
|
80
|
+
UniqueThread.logger.info('Lock lost! Killing the unique thread.')
|
84
81
|
worker.terminate
|
85
82
|
end
|
86
83
|
|
@@ -90,7 +87,7 @@ class UniqueThread
|
|
90
87
|
active_lock = self
|
91
88
|
|
92
89
|
while active_lock.acquired?
|
93
|
-
logger.debug('Lock renewed! Sleeping until next renewal attempt.')
|
90
|
+
UniqueThread.logger.debug('Lock renewed! Sleeping until next renewal attempt.')
|
94
91
|
stopwatch.sleep_until_renewal_attempt
|
95
92
|
active_lock = locksmith.renew_lock(active_lock)
|
96
93
|
end
|