lock_and_cache 1.0.3 → 1.1.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
  SHA1:
3
- metadata.gz: bbcf2cc4c2e6b8f6c7af7eb5226733eb5f9d2180
4
- data.tar.gz: ff2b4cf01475da48793e76bf5dccc1b3d437218c
3
+ metadata.gz: 240e0a726e297cc0a7ceb14a90f64ded7a6a2717
4
+ data.tar.gz: 2ebadb4c71d8e9044ccceb7e5b9025d3d1c67631
5
5
  SHA512:
6
- metadata.gz: dfa83fd496ab5fbd254cf2eab5c497990610af87ec7a013735acbc7c4281961526b592f4312e83251b550dacdccf80f6ea02e368af263fc7077641692e51f294
7
- data.tar.gz: 16aaf6d638e1f5b6c1c65cfc4d792a21ce73e5a07c164be22a53194a2f6a955346b449a7e1f4c73fab8fc017e427e15d20d73ae24d7b9593fa0147dc9c33149e
6
+ metadata.gz: 440b0ab4a18aadec5170d99600467353fb25a3d6f448bbc5e8628845941fa366c810637f526e49e4918be0f58729a85f5094372aec63addfc5ae9162ab13a142
7
+ data.tar.gz: 5ee8fd515dcfde1ad4f20c2cc4c17526a548dda99c1fa8b6160b912a5a9486d6dfdafe0b1389777f8362a362e8397090e22611b9234aab65cae4f874e640e56a
data/CHANGELOG CHANGED
@@ -1,3 +1,13 @@
1
+ 1.1.0 / 2015-08-07
2
+
3
+ * Breaking changes
4
+
5
+ * Reduce default lock expiry to 1 day instead of weird 3 days
6
+
7
+ * Enhancements
8
+
9
+ * Added :max_lock_wait option inspired by @leandromoreira
10
+
1
11
  1.0.3 / 2015-08-06
2
12
 
3
13
  * Enhancements
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Build Status](https://travis-ci.org/seamusabshere/lock_and_cache.svg?branch=master)](https://travis-ci.org/seamusabshere/lock_and_cache)
4
4
  [![Code Climate](https://codeclimate.com/github/seamusabshere/lock_and_cache/badges/gpa.svg)](https://codeclimate.com/github/seamusabshere/lock_and_cache)
5
5
  [![Dependency Status](https://gemnasium.com/seamusabshere/lock_and_cache.svg)](https://gemnasium.com/seamusabshere/lock_and_cache)
6
- [![Gem Version](https://badge.fury.io/rb/redlock.svg)](http://badge.fury.io/rb/redlock)
6
+ [![Gem Version](https://badge.fury.io/rb/lock_and_cache.svg)](http://badge.fury.io/rb/lock_and_cache)
7
7
  [![security](https://hakiri.io/github/seamusabshere/lock_and_cache/master.svg)](https://hakiri.io/github/seamusabshere/lock_and_cache/master)
8
8
  [![Inline docs](http://inch-ci.org/github/seamusabshere/lock_and_cache.svg?branch=master)](http://inch-ci.org/github/seamusabshere/lock_and_cache)
9
9
 
@@ -1,4 +1,5 @@
1
1
  require 'lock_and_cache/version'
2
+ require 'timeout'
2
3
  require 'redis'
3
4
  require 'redlock'
4
5
  require 'hash_digest'
@@ -6,8 +7,11 @@ require 'active_support'
6
7
  require 'active_support/core_ext'
7
8
 
8
9
  module LockAndCache
9
- DEFAULT_LOCK_EXPIRES = 60 * 60 * 24 * 3 * 1000 # 3 days in milliseconds
10
+ DEFAULT_LOCK_EXPIRES = 60 * 60 * 24 * 1 * 1000 # 1 day in milliseconds
10
11
  DEFAULT_LOCK_SPIN = 0.1
12
+ DEFAULT_MAX_LOCK_WAIT = 60 * 60 * 24 # 1 day in seconds
13
+
14
+ class TimeoutWaitingForLock < StandardError; end
11
15
 
12
16
  # @param redis_connection [Redis] A redis connection to be used for lock and cached value storage
13
17
  def LockAndCache.storage=(redis_connection)
@@ -53,6 +57,18 @@ module LockAndCache
53
57
  @lock_spin || DEFAULT_LOCK_SPIN
54
58
  end
55
59
 
60
+ # @param seconds [Numeric] Maximum wait time to get a lock
61
+ #
62
+ # @note Can be overridden by putting `max_lock_wait:` in your call to `#lock_and_cache`
63
+ def LockAndCache.max_lock_wait=(seconds)
64
+ @max_lock_wait = seconds.to_f
65
+ end
66
+
67
+ # @private
68
+ def LockAndCache.max_lock_wait
69
+ @max_lock_wait || DEFAULT_MAX_LOCK_WAIT
70
+ end
71
+
56
72
  # @private
57
73
  def LockAndCache.lock_manager
58
74
  @lock_manager
@@ -119,6 +135,7 @@ module LockAndCache
119
135
  expires = options['expires']
120
136
  lock_expires = options.fetch 'lock_expires', LockAndCache.lock_expires
121
137
  lock_spin = options.fetch 'lock_spin', LockAndCache.lock_spin
138
+ max_lock_wait = options.fetch 'max_lock_wait', LockAndCache.max_lock_wait
122
139
  key = LockAndCache::Key.new self, method_id, key_parts
123
140
  digest = key.digest
124
141
  storage = LockAndCache.storage
@@ -132,9 +149,11 @@ module LockAndCache
132
149
  lock_digest = 'lock/' + digest
133
150
  lock_info = nil
134
151
  begin
135
- until lock_info = lock_manager.lock(lock_digest, lock_expires)
136
- Thread.exclusive { $stderr.puts "[lock_and_cache] C1 #{key.debug}" } if debug
137
- sleep lock_spin
152
+ Timeout.timeout(max_lock_wait, TimeoutWaitingForLock) do
153
+ until lock_info = lock_manager.lock(lock_digest, lock_expires)
154
+ Thread.exclusive { $stderr.puts "[lock_and_cache] C1 #{key.debug}" } if debug
155
+ sleep lock_spin
156
+ end
138
157
  end
139
158
  Thread.exclusive { $stderr.puts "[lock_and_cache] D1 #{key.debug}" } if debug
140
159
  if storage.exists digest
@@ -150,7 +169,7 @@ module LockAndCache
150
169
  end
151
170
  end
152
171
  ensure
153
- lock_manager.unlock lock_info
172
+ lock_manager.unlock lock_info if lock_info
154
173
  end
155
174
  retval
156
175
  end
@@ -1,3 +1,3 @@
1
1
  module LockAndCache
2
- VERSION = '1.0.3'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -54,6 +54,12 @@ class Bar
54
54
  end
55
55
  end
56
56
 
57
+ def slow_click
58
+ lock_and_cache do
59
+ sleep 1
60
+ end
61
+ end
62
+
57
63
  def lock_and_cache_key
58
64
  @id
59
65
  end
@@ -142,6 +148,26 @@ describe LockAndCache do
142
148
  pool.shutdown
143
149
  end
144
150
 
151
+ it "can set a wait time" do
152
+ pool = Thread.pool 2
153
+ Thread::Pool.abort_on_exception = true
154
+ begin
155
+ old_max = LockAndCache.max_lock_wait
156
+ LockAndCache.max_lock_wait = 0.5
157
+ expect do
158
+ pool.process do
159
+ bar.slow_click
160
+ end
161
+ pool.process do
162
+ bar.slow_click
163
+ end
164
+ pool.shutdown
165
+ end.to raise_error(LockAndCache::TimeoutWaitingForLock)
166
+ ensure
167
+ LockAndCache.max_lock_wait = old_max
168
+ end
169
+ end
170
+
145
171
  end
146
172
 
147
173
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
2
  require 'lock_and_cache'
3
3
 
4
+ require 'timeout'
5
+
4
6
  require 'redis'
5
7
  LockAndCache.storage = Redis.new
6
8
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lock_and_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Seamus Abshere
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-07 00:00:00.000000000 Z
11
+ date: 2015-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport