redis-cache 0.0.0 → 1.0.0.rc1

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.
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