redis-cache 0.0.0 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ === 1.0.0.rc1 2011-06-08
2
+
3
+ * Initial release.
data/README.rdoc ADDED
@@ -0,0 +1,26 @@
1
+ = redis-cache
2
+
3
+ * https://github.com/antage/redis-cache
4
+
5
+ == DESCRIPTION
6
+
7
+ ActiveSupport cache adapter for Redis.
8
+
9
+ == SYNOPSIS
10
+
11
+ === RUBY EXAMPLE
12
+
13
+ require "active_support"
14
+
15
+ cache = ActiveSupport::Cache.lookup_store :redis_store, { :host => "localhost", :port => "6379", :db => 1, :namespace => "test-ns" }
16
+ cache.write("abc", "test") # you can use options :expires_in and :raw
17
+ cache.read("abc") # should be "test"
18
+
19
+ === RAILS EXAMPLE
20
+
21
+ # config/environments/production.rb:
22
+ Rails3::Application.configure do
23
+ ...
24
+ config.cache_store = :redis_store, { :host => "localhost", :port => 6379, :db => 1, :namespace => "rails_app" }
25
+ ...
26
+ end
data/Rakefile CHANGED
@@ -1,2 +1,7 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ require "rspec/core/rake_task"
5
+
6
+ desc "Run all examples"
7
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,95 @@
1
+ begin
2
+ require "redis"
3
+ rescue LoadError => e
4
+ $stderr.puts "You don't have redis installed in your application. Please add it to your Gemfile and run bundle install"
5
+ raise e
6
+ end
7
+
8
+ require "active_support/time"
9
+
10
+ module ActiveSupport
11
+ module Cache
12
+ class RedisStore < Store
13
+ def initialize(options = nil)
14
+ super(options)
15
+
16
+ options = { :logger => self.class.logger }.merge(options || {})
17
+ @redis = ::Redis.new(options)
18
+
19
+ extend Strategy::LocalCache
20
+ end
21
+
22
+ def reconnect
23
+ @redis and @redis.reconnect
24
+ end
25
+
26
+ def clear(options = nil)
27
+ @redis.flushdb
28
+ end
29
+
30
+ def increment(name, amount = 1, options = nil)
31
+ options = merged_options(options)
32
+ response = instrument(:increment, name, :amount => amount) do
33
+ @redis.incrby(namespaced_key(name, options), amount)
34
+ end
35
+ response
36
+ end
37
+
38
+ def decrement(name, amount = 1, options = nil)
39
+ options = merged_options(options)
40
+ response = instrument(:decrement, name, :amount => amount) do
41
+ @redis.decrby(namespaced_key(name, options), amount)
42
+ end
43
+ response
44
+ end
45
+
46
+ def read_multi(*names)
47
+ options = names.extract_options!
48
+ options = merged_options(options)
49
+ keys_to_names = Hash[names.map{|name| [namespaced_key(name, options), name]}]
50
+ raw_values = @redis.mget(*keys_to_names.keys)
51
+ values = {}
52
+ keys_to_names.keys.zip(raw_values).each do |key, value|
53
+ entry = deserialize_entry(value)
54
+ values[keys_to_names[key]] = entry.value unless entry.expired?
55
+ end
56
+ values
57
+ end
58
+
59
+ protected
60
+ def read_entry(key, options)
61
+ deserialize_entry @redis.get(key)
62
+ end
63
+
64
+ def write_entry(key, entry, options)
65
+ method = options && options[:unless_exist] ? :setnx : :set
66
+ value = options[:raw] ? entry.value : Marshal.dump(entry)
67
+
68
+ @redis.send(method, key, value)
69
+
70
+ expires_in = options[:expires_in].to_i
71
+ if expires_in > 0
72
+ if !options[:raw]
73
+ # Set the redis expire a few minutes in the future to support race condition ttls on read
74
+ expires_in += 5.minutes
75
+ end
76
+ @redis.expire(key, expires_in)
77
+ end
78
+ end
79
+
80
+ def delete_entry(key, options)
81
+ @redis.del(key)
82
+ end
83
+
84
+ private
85
+ def deserialize_entry(raw_value)
86
+ if raw_value
87
+ entry = Marshal.load(raw_value) rescue raw_value
88
+ entry.is_a?(Entry) ? entry : Entry.new(entry)
89
+ else
90
+ nil
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,151 @@
1
+ require "active_support"
2
+
3
+ describe "ActiveSupport::Cache::RedisStore" do
4
+ let!(:redis_options) do
5
+ {
6
+ :host => "localhost",
7
+ :port => 6379,
8
+ :db => 0
9
+ }
10
+ end
11
+
12
+ context "ActiveSupport::Cache.lookup_store :redis_store with options" do
13
+ subject { lambda { ActiveSupport::Cache.lookup_store :redis_store, redis_options } }
14
+
15
+ it "should not raise any exceptions" do
16
+ should_not raise_error
17
+ end
18
+
19
+ it "should return instance of ActiveSupport::Cache::RedisStore" do
20
+ subject.call.should be_instance_of(ActiveSupport::Cache::RedisStore)
21
+ end
22
+ end
23
+
24
+ context "instance" do
25
+ let!(:store) { ActiveSupport::Cache.lookup_store :redis_store, redis_options }
26
+
27
+ before(:each) do
28
+ store.clear
29
+ end
30
+
31
+ context "#clear" do
32
+ before(:each) do
33
+ store.write("abc_entity", "test")
34
+ store.clear
35
+ end
36
+
37
+ it "should clear store" do
38
+ store.read("abc_entity").should be_nil
39
+ end
40
+ end
41
+
42
+ context "with key 'abc' consisting 'test'" do
43
+ before(:each) do
44
+ store.write("abc", "test")
45
+ end
46
+
47
+ it "should be #exist?" do
48
+ store.exist?("abc").should be_true
49
+ end
50
+
51
+ it "should return 'test' when #read('abc')" do
52
+ store.read("abc").should == "test"
53
+ end
54
+ end
55
+
56
+ context "with keys 'a1', 'a2', 'a3', #read_multi('a1', 'a2', 'a3')" do
57
+ before(:each) do
58
+ store.write("a1", "test1")
59
+ store.write("a2", "test2")
60
+ store.write("a3", "test3")
61
+ end
62
+
63
+ subject { store.read_multi("a1", "a2", "a3") }
64
+
65
+ (1..3).each do |i|
66
+ it "should have key 'a#{i}'" do
67
+ should be_has_key("a#{i}")
68
+ end
69
+
70
+ it "#['a#{i}'] should == 'test#{i}'" do
71
+ subject["a#{i}"].should == "test#{i}"
72
+ end
73
+ end
74
+ end
75
+
76
+ context "with raw value 5 in key 'abc'" do
77
+ before(:each) do
78
+ store.write("abc", 5, :raw => true)
79
+ end
80
+
81
+ it "#read('abc') should return 5 as String" do
82
+ store.read("abc").should be_instance_of(String)
83
+ store.read("abc").should == "5"
84
+ end
85
+ end
86
+
87
+ context "with crazy key characters" do
88
+ let(:crazy_key) { "#/:*(<+=> )&$%@?;'\"\'`~- \t" }
89
+
90
+ it "should write the key and should not raise any exceptions" do
91
+ lambda { store.write(crazy_key, "test") }.should_not raise_error
92
+ end
93
+
94
+ it "should read the key and should not raise any exceptions" do
95
+ lambda { store.read(crazy_key) }.should_not raise_error
96
+ end
97
+ end
98
+
99
+ context "with raw key 'abc' == 5" do
100
+ before(:each) do
101
+ store.write("abc", 5, :raw => true)
102
+ end
103
+
104
+ it "#increment('abc', 2) should return 7 and change key 'abc' to 7" do
105
+ store.increment("abc", 2).should == 7
106
+ store.read("abc").to_i.should == 7
107
+ end
108
+
109
+ it "#decrement('abc', 2) should return 3 and change key 'abc' to 3" do
110
+ store.decrement("abc", 2).should == 3
111
+ store.read("abc").to_i.should == 3
112
+ end
113
+ end
114
+
115
+ context "#delete('abc')" do
116
+ before(:each) do
117
+ store.write("abc", "test")
118
+ end
119
+
120
+ it "should delete key" do
121
+ store.delete("abc")
122
+ store.exist?("abc").should be_false
123
+ end
124
+ end
125
+
126
+ context "#fetch('abc', ...)" do
127
+ before(:each) do
128
+ store.write("abc", true)
129
+ end
130
+
131
+ it "should fetch value from cache" do
132
+ store.fetch("abc") { false }.should be_true
133
+ end
134
+ end
135
+ end
136
+
137
+ context "instances with different namespaces" do
138
+ let(:store_ns1) { ActiveSupport::Cache.lookup_store :redis_store, redis_options.merge(:namespace => "ns1") }
139
+ let(:store_ns2) { ActiveSupport::Cache.lookup_store :redis_store, redis_options.merge(:namespace => "ns2") }
140
+
141
+ before(:each) do
142
+ store_ns1.write("abc", "test1")
143
+ store_ns2.write("abc", "test2")
144
+ end
145
+
146
+ it "shouldn't inteferent each to other" do
147
+ store_ns1.read("abc").should == "test1"
148
+ store_ns2.read("abc").should == "test2"
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,4 @@
1
+ require "rspec"
2
+
3
+ RSpec.configure do |c|
4
+ end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-cache
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.0.0
4
+ prerelease: 6
5
+ version: 1.0.0.rc1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Anton Ageev
@@ -10,8 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-05-25 00:00:00 +04:00
14
- default_executable:
13
+ date: 2011-06-08 00:00:00 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: activesupport
@@ -30,11 +29,33 @@ dependencies:
30
29
  requirement: &id002 !ruby/object:Gem::Requirement
31
30
  none: false
32
31
  requirements:
33
- - - ~>
32
+ - - ">="
34
33
  - !ruby/object:Gem::Version
35
34
  version: 2.2.0
36
35
  type: :runtime
37
36
  version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.6.0
46
+ type: :development
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: i18n
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: 0.6.0
57
+ type: :development
58
+ version_requirements: *id004
38
59
  description:
39
60
  email:
40
61
  - antage@gmail.com
@@ -45,13 +66,14 @@ extensions: []
45
66
  extra_rdoc_files: []
46
67
 
47
68
  files:
48
- - .gitignore
49
- - Gemfile
69
+ - README.rdoc
70
+ - History.txt
50
71
  - Rakefile
51
72
  - lib/redis-cache.rb
52
- - redis-cache.gemspec
53
- has_rdoc: true
54
- homepage: ""
73
+ - lib/active_support/cache/redis_store.rb
74
+ - spec/spec_helper.rb
75
+ - spec/redis_store_spec.rb
76
+ homepage: https://github.com/antage/redis-cache
55
77
  licenses: []
56
78
 
57
79
  post_install_message:
@@ -68,15 +90,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
90
  required_rubygems_version: !ruby/object:Gem::Requirement
69
91
  none: false
70
92
  requirements:
71
- - - ">="
93
+ - - ">"
72
94
  - !ruby/object:Gem::Version
73
- version: "0"
95
+ version: 1.3.1
74
96
  requirements: []
75
97
 
76
98
  rubyforge_project:
77
- rubygems_version: 1.6.2
99
+ rubygems_version: 1.8.5
78
100
  signing_key:
79
101
  specification_version: 3
80
102
  summary: ActiveSupport cache adapter for Redis
81
- test_files: []
82
-
103
+ test_files:
104
+ - spec/spec_helper.rb
105
+ - spec/redis_store_spec.rb
data/.gitignore DELETED
@@ -1,5 +0,0 @@
1
- *.gem
2
- .bundle
3
- Gemfile.lock
4
- pkg/*
5
- .rvmrc
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in redis-cache.gemspec
4
- gemspec
data/redis-cache.gemspec DELETED
@@ -1,20 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
-
4
- Gem::Specification.new do |s|
5
- s.name = "redis-cache"
6
- s.version = "0.0.0"
7
- s.platform = Gem::Platform::RUBY
8
- s.authors = ["Anton Ageev"]
9
- s.email = ["antage@gmail.com"]
10
- s.homepage = ""
11
- s.summary = %q{ActiveSupport cache adapter for Redis}
12
-
13
- s.files = `git ls-files`.split("\n")
14
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
- s.require_paths = ["lib"]
17
-
18
- s.add_dependency "activesupport", ">= 3.0.0"
19
- s.add_dependency "redis", "~> 2.2.0"
20
- end