visit-counter 0.1.0 → 0.1.1
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.
@@ -34,6 +34,32 @@ module VisitCounter
|
|
34
34
|
redis.set(key, 0)
|
35
35
|
end
|
36
36
|
|
37
|
+
def substract(key, by)
|
38
|
+
redis.decrby(key, by)
|
39
|
+
end
|
40
|
+
|
41
|
+
def aquire_lock!(object)
|
42
|
+
redis.setnx(lock_key(object), 1)
|
43
|
+
end
|
44
|
+
|
45
|
+
def unlock!(object)
|
46
|
+
redis.del(lock_key(object))
|
47
|
+
end
|
48
|
+
|
49
|
+
def lock_key(object)
|
50
|
+
"#{object.class.name.downcase}_#{object.id}_object_cache_lock"
|
51
|
+
end
|
52
|
+
|
53
|
+
def with_lock(object, &block)
|
54
|
+
if aquire_lock!(object)
|
55
|
+
begin
|
56
|
+
yield
|
57
|
+
ensure
|
58
|
+
unlock!(object)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
37
63
|
end
|
38
64
|
end
|
39
65
|
end
|
@@ -33,9 +33,13 @@ module VisitCounter
|
|
33
33
|
current_count + count
|
34
34
|
end
|
35
35
|
|
36
|
-
def nullify_counter_cache(name)
|
36
|
+
def nullify_counter_cache(name, substract = nil)
|
37
37
|
key = VisitCounter::Key.key(self, name)
|
38
|
-
|
38
|
+
if substract
|
39
|
+
VisitCounter::Store.engine.substract(key, substract)
|
40
|
+
else
|
41
|
+
VisitCounter::Store.engine.nullify(key)
|
42
|
+
end
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
@@ -68,8 +72,10 @@ module VisitCounter
|
|
68
72
|
end
|
69
73
|
|
70
74
|
def persist(object, staged_count, diff, name)
|
71
|
-
|
72
|
-
|
75
|
+
VisitCounter::Store.engine.with_lock(object) do
|
76
|
+
object.update_attribute(name, staged_count + diff)
|
77
|
+
object.nullify_counter_cache(name, diff)
|
78
|
+
end
|
73
79
|
end
|
74
80
|
|
75
81
|
def default_threshold(method)
|
@@ -79,6 +85,7 @@ module VisitCounter
|
|
79
85
|
0.3
|
80
86
|
end
|
81
87
|
end
|
88
|
+
|
82
89
|
end
|
83
90
|
end
|
84
91
|
end
|
@@ -16,6 +16,7 @@ class DummyObject
|
|
16
16
|
end
|
17
17
|
|
18
18
|
VisitCounter::Store::RedisStore.redis = Redis.new(host: "localhost")
|
19
|
+
VisitCounter::Store::RedisStore.redis.flushdb
|
19
20
|
|
20
21
|
describe VisitCounter do
|
21
22
|
describe "incrementing counters" do
|
@@ -110,6 +111,31 @@ describe VisitCounter do
|
|
110
111
|
end
|
111
112
|
end
|
112
113
|
|
114
|
+
describe "locked objects" do
|
115
|
+
before :each do
|
116
|
+
@d = DummyObject.new
|
117
|
+
@d.stub!(:id).and_return(1)
|
118
|
+
@d.nullify_counter_cache(:counter)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should lock object when updating" do
|
122
|
+
VisitCounter::Store.engine.should_receive(:with_lock)
|
123
|
+
VisitCounter::Helper.persist(@d, 1, 1, :counter)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should not persist if object is locked" do
|
127
|
+
VisitCounter::Store.engine.stub!(:aquire_lock!).and_return(false)
|
128
|
+
@d.should_not_receive(:update_attribute)
|
129
|
+
VisitCounter::Helper.persist(@d, 1, 1, :counter)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should persist if object is locked" do
|
133
|
+
VisitCounter::Store.engine.stub!(:aquire_lock!).and_return(true)
|
134
|
+
@d.should_receive(:update_attribute)
|
135
|
+
VisitCounter::Helper.persist(@d, 1, 1, :counter)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
113
139
|
describe "overriding the getter" do
|
114
140
|
before :all do
|
115
141
|
DummyObject.cached_counter :counter
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: visit-counter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|