lock_and_cache 0.0.5 → 0.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 +4 -4
- data/CHANGELOG +11 -0
- data/README.md +1 -1
- data/lib/lock_and_cache.rb +72 -22
- data/lib/lock_and_cache/version.rb +1 -1
- data/lock_and_cache.gemspec +1 -1
- data/spec/lock_and_cache_spec.rb +19 -8
- data/spec/spec_helper.rb +3 -0
- metadata +16 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a51c74453543a2aea1c7a2d38029ed0ca28b19ef
|
4
|
+
data.tar.gz: 279b3e00a6356f9745163de77d4583e7dda4d90a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db2cc229fd44e3e9432eb4233c23c02625066d5228aeb087e739922004a724627f7b85a4ceb3b54d89a6f6afc4963c17b57712cdf5d4ada077786107e21b625f
|
7
|
+
data.tar.gz: 396bcc439d0c3ff5bce552115fb69c858c70bcd921518ff7dfd6a770388f50ba6c2b22681273bd203d45afc82fd45a37b5bb187e51304082614b42d3d5d63f30
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
0.1.0 / 2015-01-22
|
2
|
+
|
3
|
+
* Breaking changes
|
4
|
+
|
5
|
+
* Redis only
|
6
|
+
* Now you use it inside methods (like Rails.cache.fetch) instead of outside (like cache_method)
|
7
|
+
|
8
|
+
* Enhancements
|
9
|
+
|
10
|
+
* Way simpler, no dependency on CacheMethod
|
11
|
+
|
1
12
|
0.0.5 / 2014-12-12
|
2
13
|
|
3
14
|
* Enhancements
|
data/README.md
CHANGED
data/lib/lock_and_cache.rb
CHANGED
@@ -1,36 +1,86 @@
|
|
1
1
|
require 'lock_and_cache/version'
|
2
2
|
|
3
3
|
require 'hash_digest'
|
4
|
-
require 'cache_method'
|
5
4
|
require 'active_record'
|
6
5
|
require 'with_advisory_lock'
|
7
6
|
|
8
7
|
module LockAndCache
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
8
|
+
def LockAndCache.storage=(v)
|
9
|
+
raise "only redis for now" unless v.class.to_s == 'Redis'
|
10
|
+
@storage = v
|
11
|
+
end
|
12
|
+
|
13
|
+
def LockAndCache.storage
|
14
|
+
@storage
|
15
|
+
end
|
16
|
+
|
17
|
+
def LockAndCache.flush
|
18
|
+
storage.flushdb
|
19
|
+
end
|
20
|
+
|
21
|
+
class Key
|
22
|
+
attr_reader :obj
|
23
|
+
attr_reader :kaller
|
24
|
+
|
25
|
+
def initialize(obj, kaller, parts)
|
26
|
+
@obj = obj
|
27
|
+
@kaller = kaller
|
28
|
+
@_parts = parts
|
29
|
+
end
|
30
|
+
|
31
|
+
def digest
|
32
|
+
@digest ||= ::HashDigest.digest3([obj_class_name, method_id] + parts)
|
33
|
+
end
|
34
|
+
|
35
|
+
def debug
|
36
|
+
@debug ||= [obj_class_name, method_id] + parts
|
37
|
+
end
|
38
|
+
|
39
|
+
def parts
|
40
|
+
@parts ||= @_parts.map do |v|
|
41
|
+
case v
|
42
|
+
when ::String, ::Symbol, ::Hash, ::Array
|
43
|
+
v
|
27
44
|
else
|
28
|
-
|
29
|
-
send unlocked_method_id, *args
|
45
|
+
v.respond_to?(:lock_and_cache_key) ? v.lock_and_cache_key : v.id
|
30
46
|
end
|
31
47
|
end
|
32
48
|
end
|
33
49
|
|
34
|
-
|
50
|
+
def method_id
|
51
|
+
@method_id ||= begin
|
52
|
+
kaller[0] =~ /in `(\w+)'/
|
53
|
+
$1 or raise "couldn't get method_id from #{kaller[0]}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def obj_class_name
|
58
|
+
@obj_class_name ||= (obj.class == ::Class) ? obj.name : obj.class.name
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
def lock_and_cache(*key_parts)
|
64
|
+
raise "need a block" unless block_given?
|
65
|
+
debug = (ENV['LOCK_AND_CACHE_DEBUG'] == 'true')
|
66
|
+
key = LockAndCache::Key.new self, caller, key_parts
|
67
|
+
digest = key.digest
|
68
|
+
storage = LockAndCache.storage
|
69
|
+
Thread.exclusive { $stderr.puts "[lock_and_cache] A #{key.debug}" } if debug
|
70
|
+
if storage.exists digest
|
71
|
+
return ::Marshal.load(storage.get(digest))
|
72
|
+
end
|
73
|
+
Thread.exclusive { $stderr.puts "[lock_and_cache] B #{key.debug}" } if debug
|
74
|
+
ActiveRecord::Base.with_advisory_lock(digest) do
|
75
|
+
Thread.exclusive { $stderr.puts "[lock_and_cache] C #{key.debug}" } if debug
|
76
|
+
if storage.exists digest
|
77
|
+
::Marshal.load storage.get(digest)
|
78
|
+
else
|
79
|
+
Thread.exclusive { $stderr.puts "[lock_and_cache] D #{key.debug}" } if debug
|
80
|
+
memo = yield
|
81
|
+
storage.set digest, ::Marshal.dump(memo)
|
82
|
+
memo
|
83
|
+
end
|
84
|
+
end
|
35
85
|
end
|
36
86
|
end
|
data/lock_and_cache.gemspec
CHANGED
@@ -19,7 +19,6 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_runtime_dependency 'activerecord'
|
22
|
-
spec.add_runtime_dependency 'cache_method'
|
23
22
|
spec.add_runtime_dependency 'hash_digest'
|
24
23
|
spec.add_runtime_dependency 'with_advisory_lock'
|
25
24
|
|
@@ -29,4 +28,5 @@ Gem::Specification.new do |spec|
|
|
29
28
|
spec.add_development_dependency 'pg'
|
30
29
|
spec.add_development_dependency 'rake', '~> 10.0'
|
31
30
|
spec.add_development_dependency 'rspec'
|
31
|
+
spec.add_development_dependency 'redis'
|
32
32
|
end
|
data/spec/lock_and_cache_spec.rb
CHANGED
@@ -1,17 +1,20 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
class Foo
|
4
|
+
include LockAndCache
|
5
|
+
|
4
6
|
def initialize(id)
|
5
7
|
@id = id
|
6
8
|
@count = 0
|
7
9
|
end
|
10
|
+
|
8
11
|
def click
|
9
|
-
|
12
|
+
lock_and_cache(self) do
|
13
|
+
@count += 1
|
14
|
+
end
|
10
15
|
end
|
11
16
|
|
12
|
-
|
13
|
-
lock_and_cache :click
|
14
|
-
def as_cache_key
|
17
|
+
def lock_and_cache_key
|
15
18
|
@id
|
16
19
|
end
|
17
20
|
end
|
@@ -19,10 +22,13 @@ end
|
|
19
22
|
require 'set'
|
20
23
|
$clicking = Set.new
|
21
24
|
class Bar
|
25
|
+
include LockAndCache
|
26
|
+
|
22
27
|
def initialize(id)
|
23
28
|
@id = id
|
24
29
|
@count = 0
|
25
30
|
end
|
31
|
+
|
26
32
|
def unsafe_click
|
27
33
|
Thread.exclusive do
|
28
34
|
# puts "clicking bar #{@id} - #{$clicking.to_a} - #{$clicking.include?(@id)} - #{@id == $clicking.to_a[0]}"
|
@@ -36,18 +42,23 @@ class Bar
|
|
36
42
|
end
|
37
43
|
@count
|
38
44
|
end
|
45
|
+
|
39
46
|
def click
|
40
|
-
|
47
|
+
lock_and_cache(self) do
|
48
|
+
unsafe_click
|
49
|
+
end
|
41
50
|
end
|
42
51
|
|
43
|
-
|
44
|
-
lock_and_cache :click
|
45
|
-
def as_cache_key
|
52
|
+
def lock_and_cache_key
|
46
53
|
@id
|
47
54
|
end
|
48
55
|
end
|
49
56
|
|
50
57
|
describe LockAndCache do
|
58
|
+
before do
|
59
|
+
LockAndCache.flush
|
60
|
+
end
|
61
|
+
|
51
62
|
it 'has a version number' do
|
52
63
|
expect(LockAndCache::VERSION).not_to be nil
|
53
64
|
end
|
data/spec/spec_helper.rb
CHANGED
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: 0.0
|
4
|
+
version: 0.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:
|
11
|
+
date: 2015-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: cache_method
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: hash_digest
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +136,20 @@ dependencies:
|
|
150
136
|
- - ">="
|
151
137
|
- !ruby/object:Gem::Version
|
152
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: redis
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
153
|
description: Lock and cache methods, in case things should only be calculated once
|
154
154
|
across processes.
|
155
155
|
email:
|