visit-counter 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # VisitCounter
2
2
 
3
+ [![Build Status](https://secure.travis-ci.org/KensoDev/visit-counter.png)](https://secure.travis-ci.org/KensoDev/visit-counter)
4
+
3
5
  VisitCounter is a gem which solves the annoying problem of counting visits and displaying them in real time. In an SQL database, for a site with a lot of hits, this can cause quite a lot of overhead. VisitCounter aims to solve this by using a quick key-value store to keep a delta, and only persist to the SQL DB when the delta crosses a certain percent of the saved counter.
4
6
  It can be used transparently, by overriding the accessor to the counter, or simply by using the helper functions it defines - incr_counter, read_counter, get_counter_delta and nullify_counter.
5
7
 
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+ require 'rspec/core'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ end
9
+
10
+ task :default => :spec
@@ -38,7 +38,7 @@ module VisitCounter
38
38
  redis.decrby(key, by)
39
39
  end
40
40
 
41
- def aquire_lock!(object)
41
+ def acquire_lock(object)
42
42
  redis.setnx(lock_key(object), 1)
43
43
  end
44
44
 
@@ -51,7 +51,7 @@ module VisitCounter
51
51
  end
52
52
 
53
53
  def with_lock(object, &block)
54
- if aquire_lock!(object)
54
+ if acquire_lock(object)
55
55
  begin
56
56
  yield
57
57
  ensure
@@ -63,4 +63,4 @@ module VisitCounter
63
63
  end
64
64
  end
65
65
  end
66
- end
66
+ end
@@ -1,3 +1,3 @@
1
1
  module VisitCounter
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -4,7 +4,7 @@ module VisitCounter
4
4
  base.class_eval do
5
5
  class << self
6
6
  #defining class instance attributes
7
- attr_accessor :visit_counter_threshold, :visit_counter_threshold_method
7
+ attr_accessor :visit_counter_threshold, :visit_counter_threshold_method, :persist_with_callbacks
8
8
  end
9
9
  end
10
10
  base.send(:include, InstanceMethods)
@@ -73,7 +73,12 @@ module VisitCounter
73
73
 
74
74
  def persist(object, staged_count, diff, name)
75
75
  VisitCounter::Store.engine.with_lock(object) do
76
- object.update_attribute(name, staged_count + diff)
76
+ if object.class.persist_with_callbacks
77
+ object.send("#{name}=", staged_count + diff )
78
+ object.save
79
+ else
80
+ object.update_attribute(name, staged_count + diff)
81
+ end
77
82
  object.nullify_counter_cache(name, diff)
78
83
  end
79
84
  end
@@ -3,12 +3,16 @@ require "spec_helper"
3
3
  class DummyObject
4
4
  include VisitCounter
5
5
 
6
- attr_accessor :counter
6
+ attr_accessor :counter, :persist_with_callbacks
7
7
 
8
8
  def update_attribute(attribute, value)
9
9
  self.send("#{attribute}=", value)
10
10
  end
11
11
 
12
+ def save
13
+ nil
14
+ end
15
+
12
16
  def read_attribute(name)
13
17
  #yeah, evals are evil, but it works and it's for testing purposes only. we assume read_attribute is defined the same as in AR wherever we include this module
14
18
  eval("@#{name}")
@@ -124,13 +128,13 @@ describe VisitCounter do
124
128
  end
125
129
 
126
130
  it "should not persist if object is locked" do
127
- VisitCounter::Store.engine.stub!(:aquire_lock!).and_return(false)
131
+ VisitCounter::Store.engine.stub!(:acquire_lock).and_return(false)
128
132
  @d.should_not_receive(:update_attribute)
129
133
  VisitCounter::Helper.persist(@d, 1, 1, :counter)
130
134
  end
131
135
 
132
136
  it "should persist if object is locked" do
133
- VisitCounter::Store.engine.stub!(:aquire_lock!).and_return(true)
137
+ VisitCounter::Store.engine.stub!(:acquire_lock).and_return(true)
134
138
  @d.should_receive(:update_attribute)
135
139
  VisitCounter::Helper.persist(@d, 1, 1, :counter)
136
140
  end
@@ -157,5 +161,15 @@ describe VisitCounter do
157
161
  @d.counter.should == 11
158
162
  end
159
163
  end
164
+
165
+ describe "persist with callbacks" do
166
+ it "should use save method" do
167
+ @d = DummyObject.new
168
+ @d.class.persist_with_callbacks = true
169
+ @d.stub!(:id).and_return(1)
170
+ @d.should_receive(:save)
171
+ @d.incr_counter :counter
172
+ end
173
+ end
160
174
 
161
- end
175
+ end
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.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,56 +9,56 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-24 00:00:00.000000000 Z
12
+ date: 2013-04-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
+ prerelease: false
16
17
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
21
  version: '0'
22
+ none: false
22
23
  type: :development
23
- prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
25
  requirements:
27
26
  - - ! '>='
28
27
  - !ruby/object:Gem::Version
29
28
  version: '0'
29
+ none: false
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: rake
32
+ prerelease: false
32
33
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
37
  version: 0.9.2
38
+ none: false
38
39
  type: :development
39
- prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
41
  requirements:
43
42
  - - ~>
44
43
  - !ruby/object:Gem::Version
45
44
  version: 0.9.2
45
+ none: false
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: redis
48
+ prerelease: false
48
49
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
50
  requirements:
51
51
  - - ! '>='
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
+ none: false
54
55
  type: :runtime
55
- prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
57
  requirements:
59
58
  - - ! '>='
60
59
  - !ruby/object:Gem::Version
61
60
  version: '0'
61
+ none: false
62
62
  description: Simple counter increment which only writes to DB once in a while
63
63
  email:
64
64
  - tcaspy@gmail.com
@@ -90,17 +90,17 @@ rdoc_options: []
90
90
  require_paths:
91
91
  - lib
92
92
  required_ruby_version: !ruby/object:Gem::Requirement
93
- none: false
94
93
  requirements:
95
94
  - - ! '>='
96
95
  - !ruby/object:Gem::Version
97
96
  version: '0'
98
- required_rubygems_version: !ruby/object:Gem::Requirement
99
97
  none: false
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
99
  requirements:
101
100
  - - ! '>='
102
101
  - !ruby/object:Gem::Version
103
102
  version: '0'
103
+ none: false
104
104
  requirements: []
105
105
  rubyforge_project:
106
106
  rubygems_version: 1.8.24