lock_and_cache 5.0.0 → 6.0.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: 186a1eea8f6cc7f0d72ed2ccd5cc1c8f19f3c605
4
- data.tar.gz: 80d956322883072ea8e23f58df3710bc0bc6571c
3
+ metadata.gz: 9b00954eb152d6691ec74bbd0db1ed1a203293fb
4
+ data.tar.gz: 9e41793803b95b133756e37f59cfd7715d71750a
5
5
  SHA512:
6
- metadata.gz: ff3c3bde1ab6eddc04217ee3c64d1877d75f19c24155a110cae23d5019468cae2bf7fc58e695ab5627277c1087c49aaf18f2cf952b109c375eeeaf122738fabf
7
- data.tar.gz: af5b4021a8d5e5e8ab6fbc7fe80464f9f6d0e2e1ddeeb5f7a97371406414000d464b574a0a01813f9a0b3d11bdb105c0730aa1fe8ffd9861bd9af6297f879378
6
+ metadata.gz: e57de257fd2d8c19e3c1ea657e155ce3a6abc2d579fbacac42ea1c7f1469408ae0c360492f98ac219cbe90f10ddc14b1655a804ad70636a2e9fb78b58479057f
7
+ data.tar.gz: 77604654cebc124eb594e7824cf8c318d7abc2261082802052f66475f06886826521ea89c7d9c82ffc46eeb823763b2b97a8955b1866cd4312cb9bec98546fe0
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ 6.0.0
2
+
3
+ * Breaking changes
4
+
5
+ * Set lock_storage and cache_storage separately
6
+
1
7
  5.0.0
2
8
 
3
9
  * Enhancements / breaking changes
data/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/seamusabshere/lock_and_cache.svg?branch=master&v=2.2.0)](https://travis-ci.org/seamusabshere/lock_and_cache)
4
4
  [![Code Climate](https://codeclimate.com/github/seamusabshere/lock_and_cache/badges/gpa.svg?v=2.2.0)](https://codeclimate.com/github/seamusabshere/lock_and_cache)
5
- [![Dependency Status](https://gemnasium.com/seamusabshere/lock_and_cache.svg?v=2.2.0)](https://gemnasium.com/seamusabshere/lock_and_cache)
6
5
  [![Gem Version](https://badge.fury.io/rb/lock_and_cache.svg?v=2.2.0)](http://badge.fury.io/rb/lock_and_cache)
7
6
  [![Security](https://hakiri.io/github/seamusabshere/lock_and_cache/master.svg?v=2.2.0)](https://hakiri.io/github/seamusabshere/lock_and_cache/master)
8
7
  [![Inline docs](http://inch-ci.org/github/seamusabshere/lock_and_cache.svg?branch=master&v=2.2.0)](http://inch-ci.org/github/seamusabshere/lock_and_cache)
@@ -14,7 +13,8 @@ Most caching libraries don't do locking, meaning that >1 process can be calculat
14
13
  ## Quickstart
15
14
 
16
15
  ```ruby
17
- LockAndCache.storage = Redis.new
16
+ LockAndCache.lock_storage = Redis.new db: 3
17
+ LockAndCache.cache_storage = Redis.new db: 4
18
18
 
19
19
  LockAndCache.lock_and_cache(:stock_price, {company: 'MSFT', date: '2015-05-05'}, expires: 10, nil_expires: 1) do
20
20
  # get yer stock quote
@@ -77,7 +77,8 @@ If an error is raised during calculation, that error is propagated to all waiter
77
77
  ### Setup
78
78
 
79
79
  ```ruby
80
- LockAndCache.storage = Redis.new
80
+ LockAndCache.lock_storage = Redis.new db: 3
81
+ LockAndCache.cache_storage = Redis.new db: 4
81
82
  ```
82
83
 
83
84
  It will use this redis for both locking and storing cached values.
@@ -205,7 +206,8 @@ You can expire nil values with a different timeout (`nil_expires`) than other va
205
206
 
206
207
  ## Tunables
207
208
 
208
- * `LockAndCache.storage=[redis]`
209
+ * `LockAndCache.lock_storage=[redis]`
210
+ * `LockAndCache.cache_storage=[redis]`
209
211
  * `ENV['LOCK_AND_CACHE_DEBUG']='true'` if you want some debugging output on `$stderr`
210
212
 
211
213
  ## Few dependencies
@@ -20,15 +20,26 @@ module LockAndCache
20
20
 
21
21
  class TimeoutWaitingForLock < StandardError; end
22
22
 
23
- # @param redis_connection [Redis] A redis connection to be used for lock and cached value storage
24
- def LockAndCache.storage=(redis_connection)
23
+ # @param redis_connection [Redis] A redis connection to be used for lock storage
24
+ def LockAndCache.lock_storage=(redis_connection)
25
25
  raise "only redis for now" unless redis_connection.class.to_s == 'Redis'
26
- @storage = redis_connection
26
+ @lock_storage = redis_connection
27
27
  end
28
28
 
29
29
  # @return [Redis] The redis connection used for lock and cached value storage
30
- def LockAndCache.storage
31
- @storage
30
+ def LockAndCache.lock_storage
31
+ @lock_storage
32
+ end
33
+
34
+ # @param redis_connection [Redis] A redis connection to be used for cached value storage
35
+ def LockAndCache.cache_storage=(redis_connection)
36
+ raise "only redis for now" unless redis_connection.class.to_s == 'Redis'
37
+ @cache_storage = redis_connection
38
+ end
39
+
40
+ # @return [Redis] The redis connection used for cached value storage
41
+ def LockAndCache.cache_storage
42
+ @cache_storage
32
43
  end
33
44
 
34
45
  # @param logger [Logger] A logger.
@@ -41,13 +52,22 @@ module LockAndCache
41
52
  @logger
42
53
  end
43
54
 
44
- # Flush LockAndCache's storage.
55
+ # Flush LockAndCache's cached value storage.
56
+ #
57
+ # @note If you are sharing a redis database, it will clear it...
58
+ #
59
+ # @note If you want to clear a single key, try `LockAndCache.clear(key)` (standalone mode) or `#lock_and_cache_clear(method_id, *key_parts)` in context mode.
60
+ def LockAndCache.flush_cache
61
+ cache_storage.flushdb
62
+ end
63
+
64
+ # Flush LockAndCache's lock storage.
45
65
  #
46
66
  # @note If you are sharing a redis database, it will clear it...
47
67
  #
48
68
  # @note If you want to clear a single key, try `LockAndCache.clear(key)` (standalone mode) or `#lock_and_cache_clear(method_id, *key_parts)` in context mode.
49
- def LockAndCache.flush
50
- storage.flushdb
69
+ def LockAndCache.flush_locks
70
+ lock_storage.flushdb
51
71
  end
52
72
 
53
73
  # Lock and cache based on a key.
@@ -32,8 +32,12 @@ module LockAndCache
32
32
  @lock_digest ||= key.lock_digest
33
33
  end
34
34
 
35
- def storage
36
- @storage ||= LockAndCache.storage or raise("must set LockAndCache.storage=[Redis]")
35
+ def lock_storage
36
+ @lock_storage ||= LockAndCache.lock_storage or raise("must set LockAndCache.lock_storage=[Redis]")
37
+ end
38
+
39
+ def cache_storage
40
+ @cache_storage ||= LockAndCache.cache_storage or raise("must set LockAndCache.cache_storage=[Redis]")
37
41
  end
38
42
 
39
43
  def load_existing(existing)
@@ -51,7 +55,7 @@ module LockAndCache
51
55
  raise "heartbeat_expires must be >= 2 seconds" unless heartbeat_expires >= 2
52
56
  heartbeat_frequency = (heartbeat_expires / 2).ceil
53
57
  LockAndCache.logger.debug { "[lock_and_cache] A1 #{key.debug} #{Base64.encode64(digest).strip} #{Digest::SHA1.hexdigest digest}" }
54
- if storage.exists(digest) and (existing = storage.get(digest)).is_a?(String)
58
+ if cache_storage.exists(digest) and (existing = cache_storage.get(digest)).is_a?(String)
55
59
  return load_existing(existing)
56
60
  end
57
61
  LockAndCache.logger.debug { "[lock_and_cache] B1 #{key.debug} #{Base64.encode64(digest).strip} #{Digest::SHA1.hexdigest digest}" }
@@ -60,14 +64,14 @@ module LockAndCache
60
64
  acquired = false
61
65
  begin
62
66
  Timeout.timeout(max_lock_wait, TimeoutWaitingForLock) do
63
- until storage.set(lock_digest, lock_secret, nx: true, ex: heartbeat_expires)
67
+ until lock_storage.set(lock_digest, lock_secret, nx: true, ex: heartbeat_expires)
64
68
  LockAndCache.logger.debug { "[lock_and_cache] C1 #{key.debug} #{Base64.encode64(digest).strip} #{Digest::SHA1.hexdigest digest}" }
65
69
  sleep rand
66
70
  end
67
71
  acquired = true
68
72
  end
69
73
  LockAndCache.logger.debug { "[lock_and_cache] D1 #{key.debug} #{Base64.encode64(digest).strip} #{Digest::SHA1.hexdigest digest}" }
70
- if storage.exists(digest) and (existing = storage.get(digest)).is_a?(String)
74
+ if cache_storage.exists(digest) and (existing = cache_storage.get(digest)).is_a?(String)
71
75
  LockAndCache.logger.debug { "[lock_and_cache] E1 #{key.debug} #{Base64.encode64(digest).strip} #{Digest::SHA1.hexdigest digest}" }
72
76
  retval = load_existing existing
73
77
  end
@@ -83,8 +87,8 @@ module LockAndCache
83
87
  break if done
84
88
  LockAndCache.logger.debug { "[lock_and_cache] heartbeat2 #{key.debug} #{Base64.encode64(digest).strip} #{Digest::SHA1.hexdigest digest}" }
85
89
  # FIXME use lua to check the value
86
- raise "unexpectedly lost lock for #{key.debug}" unless storage.get(lock_digest) == lock_secret
87
- storage.set lock_digest, lock_secret, xx: true, ex: heartbeat_expires
90
+ raise "unexpectedly lost lock for #{key.debug}" unless lock_storage.get(lock_digest) == lock_secret
91
+ lock_storage.set lock_digest, lock_secret, xx: true, ex: heartbeat_expires
88
92
  end
89
93
  end
90
94
  begin
@@ -100,32 +104,32 @@ module LockAndCache
100
104
  end
101
105
  end
102
106
  ensure
103
- storage.del lock_digest if acquired
107
+ lock_storage.del lock_digest if acquired
104
108
  end
105
109
  retval
106
110
  end
107
111
 
108
112
  def set_error(exception)
109
- storage.set digest, ::Marshal.dump(ERROR_MAGIC_KEY => exception.message), ex: 1
113
+ cache_storage.set digest, ::Marshal.dump(ERROR_MAGIC_KEY => exception.message), ex: 1
110
114
  end
111
115
 
112
116
  NIL = Marshal.dump nil
113
117
  def set_nil
114
118
  if nil_expires
115
- storage.set digest, NIL, ex: nil_expires
119
+ cache_storage.set digest, NIL, ex: nil_expires
116
120
  elsif expires
117
- storage.set digest, NIL, ex: expires
121
+ cache_storage.set digest, NIL, ex: expires
118
122
  else
119
- storage.set digest, NIL
123
+ cache_storage.set digest, NIL
120
124
  end
121
125
  end
122
126
 
123
127
  def set_non_nil(retval)
124
128
  raise "expected not null #{retval.inspect}" if retval.nil?
125
129
  if expires
126
- storage.set digest, ::Marshal.dump(retval), ex: expires
130
+ cache_storage.set digest, ::Marshal.dump(retval), ex: expires
127
131
  else
128
- storage.set digest, ::Marshal.dump(retval)
132
+ cache_storage.set digest, ::Marshal.dump(retval)
129
133
  end
130
134
  end
131
135
  end
@@ -98,18 +98,17 @@ module LockAndCache
98
98
  end
99
99
 
100
100
  def locked?
101
- LockAndCache.storage.exists lock_digest
101
+ LockAndCache.lock_storage.exists lock_digest
102
102
  end
103
103
 
104
104
  def cached?
105
- LockAndCache.storage.exists digest
105
+ LockAndCache.cache_storage.exists digest
106
106
  end
107
107
 
108
108
  def clear
109
109
  LockAndCache.logger.debug { "[lock_and_cache] clear #{debug} #{Base64.encode64(digest).strip} #{Digest::SHA1.hexdigest digest}" }
110
- storage = LockAndCache.storage
111
- storage.del digest
112
- storage.del lock_digest
110
+ LockAndCache.cache_storage.del digest
111
+ LockAndCache.lock_storage.del lock_digest
113
112
  end
114
113
 
115
114
  alias debug key
@@ -1,3 +1,3 @@
1
1
  module LockAndCache
2
- VERSION = '5.0.0'
2
+ VERSION = '6.0.0'
3
3
  end
@@ -140,7 +140,8 @@ end
140
140
 
141
141
  describe LockAndCache do
142
142
  before do
143
- LockAndCache.flush
143
+ LockAndCache.flush_locks
144
+ LockAndCache.flush_cache
144
145
  end
145
146
 
146
147
  it 'has a version number' do
@@ -4,7 +4,8 @@ require 'lock_and_cache'
4
4
  require 'timeout'
5
5
 
6
6
  require 'redis'
7
- LockAndCache.storage = Redis.new
7
+ LockAndCache.lock_storage = Redis.new db: 3
8
+ LockAndCache.cache_storage = Redis.new db: 4
8
9
 
9
10
  require 'thread/pool'
10
11
 
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: 5.0.0
4
+ version: 6.0.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: 2018-09-19 00:00:00.000000000 Z
11
+ date: 2018-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport