redlock_for_collection 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3378d1d9df7bf21c5b3193f6718114f5a757920b
4
- data.tar.gz: 8fc50b970e8117bff0c304a4147616280369f58a
3
+ metadata.gz: 4937ef3a7fc3cc932e53c070779e4111f570003c
4
+ data.tar.gz: ea8133464f2c73a36ca2688676908ece989dfc06
5
5
  SHA512:
6
- metadata.gz: fa0d2f377be01b32396ab97ed61b273f4598be78b8f0710b0e524b7fc6f5e26d0f5e1ee075d42e610e8d766331cc1eea3a255d702ca58cdfa1a0437b6f12cc3d
7
- data.tar.gz: 2d36951d26cdfed4fdb956ec49f7f98d368d41150d394427ee0734a4d1df76d407741b7752e5d1414002906acdcd506f002c7c4018a3a49d011fb079a2ac2d42
6
+ metadata.gz: 64e5152770347cf2cbcfa4f74f0b60e6c882b74bf9239bd5b0da689dbbfddad25e3efb9275f5c9b5079d1da74e60e73ba0b509b3edc0d078cdc588187a8c6f06
7
+ data.tar.gz: 16afb06e26f1f7c7dc85e3ba0850fc3183feb42eaa744d1492596e1c981402733e7463c8b769dbc101458f325f57748691df4a5c35017585ef0ee4652bc072fe
@@ -5,6 +5,8 @@ module RedlockForCollection
5
5
  DEFAULT_KEY_METHOD = 'key'.freeze
6
6
  DEFAULT_KEY_PREFIX = 'prefix'.freeze
7
7
 
8
+ LockPair = Struct.new(:object, :lock_info, :status)
9
+
8
10
  attr_reader :objects, :options, :pool
9
11
 
10
12
  def initialize(objects, options, pool)
@@ -15,47 +17,32 @@ module RedlockForCollection
15
17
  init_options
16
18
  end
17
19
 
18
-
19
20
  def lock(&block)
20
- locked_objects = []
21
- unlocked_objects = []
22
-
23
- locks_info = []
24
- expired_locks_info = []
21
+ lock_pairs = []
25
22
 
23
+ start_time = (Time.now.to_f * 1000).to_i
26
24
  @objects.each do |object|
27
25
  @pool.with do |redlock|
28
26
  lock_info = redlock.lock(build_key_for(object), @options[:ttl])
29
-
30
- # Check if ttl is enough
31
- if lock_info && (lock_info[:validity] > (@options[:min_validity]))
32
- locked_objects << object
33
- locks_info << lock_info
34
- else
35
- expired_locks_info << lock_info if lock_info
36
- unlocked_objects << object
37
- end
27
+ lock_pairs << LockPair.new(object, lock_info)
38
28
  end
39
29
  end
30
+ end_time = (Time.now.to_f * 1000).to_i
31
+
32
+ separated_pairs = separate_expired_pairs(lock_pairs, end_time - start_time)
40
33
 
41
34
  begin
42
- block.yield(locked_objects, unlocked_objects)
35
+ separated_pairs[:valid].map(&:object)
36
+ separated_pairs[:expired].map(&:object)
37
+ block.yield(separated_pairs[:valid].map(&:object), separated_pairs[:expired].map(&:object))
43
38
  ensure
44
39
  # Release the all acquired locks
45
- unlock(expired_locks_info)
46
- unlock(locks_info)
40
+ unlock(lock_pairs)
47
41
  end
48
42
  end
49
43
 
50
-
51
44
  protected
52
45
 
53
- def unlock(locks_info)
54
- @pool.with do |redlock|
55
- locks_info.each { |lock_info| redlock.unlock(lock_info) }
56
- end
57
- end
58
-
59
46
  def init_options
60
47
  @options[:key_prefix] ||= DEFAULT_KEY_PREFIX
61
48
  @options[:key_method] ||= DEFAULT_KEY_METHOD
@@ -63,10 +50,39 @@ module RedlockForCollection
63
50
  @options[:ttl] ||= DEFAULT_TTL
64
51
  end
65
52
 
53
+ # @param lock_pairs [Array<LockPair>]
54
+ def unlock(lock_pairs)
55
+ @pool.with do |redlock|
56
+ lock_pairs.each do |lock_pair|
57
+ redlock.unlock(lock_pair.lock_info) if lock_pair.lock_info
58
+ end
59
+ end
60
+ end
61
+
66
62
  def build_key_for(object)
67
63
  (@options[:key_prefix]) + object.send(@options[:key_method]).to_s
68
64
  end
69
65
 
66
+ # @param lock_pairs [Array<LockPair>]
67
+ # @param elapsed [Integer]
68
+ # @return [Hash]
69
+ def separate_expired_pairs(lock_pairs, elapsed)
70
+ expired_pairs = []
71
+ valid_pairs = []
72
+
73
+ lock_pairs.each do |lock_pair|
74
+ if lock_pair.lock_info && ((lock_pair.lock_info[:validity] - elapsed) > (@options[:min_validity]))
75
+ lock_pair.status = :valid
76
+ valid_pairs << lock_pair
77
+ else
78
+ lock_pair.status= :expired
79
+ expired_pairs << lock_pair
80
+ end
81
+ end
82
+
83
+ { valid: valid_pairs, expired: expired_pairs }
84
+ end
85
+
70
86
  end
71
87
  end
72
88
 
@@ -14,20 +14,16 @@ module RedlockForCollection
14
14
  @pool_size = 5
15
15
  @pool_timeout = 5
16
16
  @redis_urls = ['redis://localhost:6379']
17
- @retry_delay = 5
17
+ @retry_delay = 50
18
18
  @retry_count = 5
19
19
  @pool = nil
20
20
  end
21
21
 
22
-
23
22
  def pool
24
- @pool|| begin
25
- @pool = ConnectionPool.new(size: @pool_size, timeout: @pool_timeout) do
23
+ @pool ||= ConnectionPool.new(size: @pool_size, timeout: @pool_timeout) do
26
24
  Redlock::Client.new(@redis_urls, retry_delay: @retry_delay, retry_count: @retry_count)
27
- end
28
25
  end
29
26
  end
30
-
31
27
  end
32
28
  end
33
29
 
@@ -1,3 +1,3 @@
1
1
  module RedlockForCollection
2
- VERSION = '0.1.1'.freeze
2
+ VERSION = '0.1.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redlock_for_collection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - CoolElvis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-16 00:00:00.000000000 Z
11
+ date: 2016-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler