lawnchair 0.4.0 → 0.5.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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.5.0
data/lawnchair.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{lawnchair}
8
- s.version = "0.4.0"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Shane Wolf"]
12
- s.date = %q{2010-02-11}
12
+ s.date = %q{2010-02-12}
13
13
  s.description = %q{Very simple caching mechanism for arbitrary pieces of resoucre ruby code using Redis as the distributed (or local) cache}
14
14
  s.email = %q{shanewolf@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -24,11 +24,20 @@ Gem::Specification.new do |s|
24
24
  "VERSION",
25
25
  "lawnchair.gemspec",
26
26
  "lib/lawnchair.rb",
27
+ "lib/storage_engine/abstract.rb",
28
+ "lib/storage_engine/composite.rb",
29
+ "lib/storage_engine/in_process.rb",
30
+ "lib/storage_engine/redis.rb",
31
+ "lib/view/helper.rb",
27
32
  "spec/lawnchair_spec.rb",
28
33
  "spec/spec.opts",
29
34
  "spec/spec_helper.rb",
30
35
  "spec/speed.rb",
31
- "spec/speed_results.png"
36
+ "spec/speed_results.png",
37
+ "spec/storage_engine/abstract_spec.rb",
38
+ "spec/storage_engine/composite_spec.rb",
39
+ "spec/storage_engine/in_process_spec.rb",
40
+ "spec/storage_engine/redis_spec.rb"
32
41
  ]
33
42
  s.homepage = %q{http://github.com/gizm0duck/lawnchair}
34
43
  s.rdoc_options = ["--charset=UTF-8"]
@@ -38,7 +47,11 @@ Gem::Specification.new do |s|
38
47
  s.test_files = [
39
48
  "spec/lawnchair_spec.rb",
40
49
  "spec/spec_helper.rb",
41
- "spec/speed.rb"
50
+ "spec/speed.rb",
51
+ "spec/storage_engine/abstract_spec.rb",
52
+ "spec/storage_engine/composite_spec.rb",
53
+ "spec/storage_engine/in_process_spec.rb",
54
+ "spec/storage_engine/redis_spec.rb"
42
55
  ]
43
56
 
44
57
  if s.respond_to? :specification_version then
data/lib/lawnchair.rb CHANGED
@@ -1,72 +1,34 @@
1
- require 'rubygems'
2
- require 'redis'
1
+ Dir[File.dirname(__FILE__) + '/storage_engine/*.rb'].each {|file| require file }
2
+ require 'view/helper'
3
3
 
4
4
  module Lawnchair
5
-
6
- class << self
7
- attr_reader :redis
8
-
9
- def connectdb(redis=nil)
10
- @redis ||= Redis.new(:db => 11)
11
- end
12
-
13
- def flushdb
14
- redis.flushdb
15
- end
16
- end
17
-
18
5
  class Cache
19
- @@in_process_store = {}
20
-
21
- def self.in_process_store
22
- @@in_process_store
23
- end
24
-
25
- def self.me(options = {}, &block)
26
- raise "Cache key please!" unless options.has_key?(:key)
27
-
6
+ def self.me(key, options={}, &block)
28
7
  if options[:in_process]
29
- key_exists = @@in_process_store.has_key?([compute_key(options[:key])])
8
+ store = initialize_composite_store
30
9
  else
31
- key_exists = exists?(options[:key])
10
+ store = Lawnchair::StorageEngine::Redis
32
11
  end
33
-
34
- if key_exists && !options[:force]
35
- if options[:in_process]
36
- Marshal.load(@@in_process_store[compute_key(options[:key])])
37
- else
38
- Marshal.load(Lawnchair.redis[compute_key(options[:key])])
39
- end
40
- else
41
- if options[:in_process] && exists?(options[:key])
42
- cached_val = Lawnchair.redis[compute_key(options[:key])]
43
- @@in_process_store[compute_key(options[:key])] = cached_val
44
- return Marshal.dump(cached_val)
45
- end
46
-
47
- val = block.call
48
- expires_in = compute_expiry(options[:expires_in])
49
- dumped_val = Marshal.dump(val)
50
- @@in_process_store[compute_key(options[:key])] = dumped_val if options[:in_process]
51
- Lawnchair.redis.set(compute_key(options[:key]), dumped_val, expires_in)
52
- return val
53
- end
54
- end
55
-
56
- def self.compute_key(key)
57
- "Lawnchair:#{key}"
12
+ store.fetch(key, options, &block)
58
13
  end
59
14
 
60
- def self.expire(key)
61
- Lawnchair.redis.del(compute_key(key))
15
+ def self.initialize_composite_store
16
+ composite_store = Lawnchair::StorageEngine::Composite.new
17
+ composite_store.register_storage_engine(Lawnchair::StorageEngine::InProcess)
18
+ composite_store.register_storage_engine(Lawnchair::StorageEngine::Redis)
19
+ composite_store
62
20
  end
63
-
64
- def self.exists?(key)
65
- return Lawnchair.redis.exists(compute_key(key))
21
+ end
22
+
23
+ class << self
24
+ attr_reader :redis
25
+
26
+ def connectdb(redis=nil)
27
+ @redis = (redis || Redis.new(:db => 11))
66
28
  end
67
-
68
- def self.compute_expiry(seconds)
69
- seconds || 3600
29
+
30
+ def flushdb
31
+ redis.flushdb
70
32
  end
71
33
  end
72
34
  end
@@ -0,0 +1,37 @@
1
+ module Lawnchair
2
+ module StorageEngine
3
+ class Abstract
4
+ class << self
5
+ attr_reader :cache_container
6
+
7
+ def cache_container
8
+ @cache_container ||= {}
9
+ end
10
+
11
+ def fetch(key, options, &block)
12
+ if exists?(key)
13
+ value = get(key, options)
14
+ else
15
+ value = block.call
16
+ set(key, value, options)
17
+ end
18
+ value
19
+ end
20
+
21
+ def get(key, options={})
22
+ if options[:raw]
23
+ cache_container[computed_key(key)]
24
+ else
25
+ exists?(key) ? Marshal.load(cache_container[computed_key(key)]) : nil
26
+ end
27
+ end
28
+
29
+ def computed_key(key)
30
+ raise "Missiing key" if key.nil? || key.empty?
31
+ prefix = "Lawnchair"
32
+ "#{prefix}:#{key}"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ module Lawnchair
2
+ module StorageEngine
3
+ class Composite
4
+ attr_reader :storage_engines
5
+
6
+ def initialize
7
+ @storage_engines = []
8
+ end
9
+
10
+ def register_storage_engine(storage_engine)
11
+ storage_engines << storage_engine
12
+ end
13
+
14
+ def fetch(key, options, &block)
15
+ raise "No Storage Engines Configured" if storage_engines.empty?
16
+
17
+ value, index = find_in_storage(key, options)
18
+ value ||= yield
19
+ place_in_storage(key, value, options, index)
20
+ end
21
+
22
+ private
23
+
24
+ def find_in_storage(key, options)
25
+ value, index = nil, nil
26
+ storage_engines.each_with_index do |storage_engine, i|
27
+ if storage_engine.exists?(key)
28
+ value = storage_engine.get(key, options)
29
+ index = i
30
+ break
31
+ end
32
+ end
33
+ return value, index
34
+ end
35
+
36
+ def place_in_storage(key, value, options, index)
37
+ storage_engines.each_with_index do |storage_engine, i|
38
+ break if i == index
39
+ storage_engine.set(key, value, options)
40
+ end
41
+ value
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,29 @@
1
+ module Lawnchair
2
+ module StorageEngine
3
+ class InProcess < Abstract
4
+ @@cache_container = {}
5
+ class << self
6
+
7
+ def cache_container
8
+ @@cache_container
9
+ end
10
+
11
+ def set(key, value, options={})
12
+ if options[:raw]
13
+ cache_container[computed_key(key)] = value
14
+ else
15
+ cache_container[computed_key(key)] = Marshal.dump(value)
16
+ end
17
+ end
18
+
19
+ def exists?(key)
20
+ cache_container.has_key?(computed_key(key))
21
+ end
22
+
23
+ def expire!(key)
24
+ cache_container.delete(computed_key(key))
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ module Lawnchair
2
+ module StorageEngine
3
+ class Redis < Abstract
4
+ class << self
5
+ def cache_container
6
+ Lawnchair.redis
7
+ end
8
+
9
+ def set(key, value, options={})
10
+ ttl = options[:expires_in] || 3600
11
+ if options[:raw]
12
+ cache_container.set(computed_key(key), value, ttl)
13
+ else
14
+ cache_container.set(computed_key(key), Marshal.dump(value), ttl)
15
+ end
16
+ end
17
+
18
+ def exists?(key)
19
+ cache_container.exists(computed_key(key))
20
+ end
21
+
22
+ def expire!(key)
23
+ cache_container.del(computed_key(key))
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ require 'action_view'
2
+ module Lawnchair
3
+ module View
4
+ module Helper
5
+ def lawnchair_cache(key, &block)
6
+ rendered_value = Lawnchair::Cache.me({:key => key, :raw => true}) do
7
+ capture(&block)
8
+ end
9
+ concat(rendered_value)
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ ActionView::Base.send(:include, Lawnchair::View::Helper)
@@ -2,94 +2,29 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "Lawnchair::Cache" do
4
4
  describe ".me" do
5
- it "raises an exception if no key is given" do
6
- lambda do
7
- Lawnchair::Cache.me { 1 }
8
- end.should raise_error("Cache key please!")
9
- end
10
-
11
5
  it "returns the value if it exists" do
12
6
  expected_object = [1,2,3,4]
13
- Lawnchair::Cache.me(:key => "marshalled_array") { expected_object }
7
+ Lawnchair::Cache.me("marshalled_array") { expected_object }
14
8
 
15
- x = Lawnchair::Cache.me(:key => "marshalled_array") { "JUNK DATA" }
9
+ x = Lawnchair::Cache.me("marshalled_array") { "JUNK DATA" }
16
10
  x.should == expected_object
17
11
  end
18
12
 
19
13
  it "marshalls the object into redis" do
20
14
  expected_object = [1,2,3,4]
21
- Lawnchair::Cache.me(:key => "marshalled_array") { expected_object }
15
+ Lawnchair::Cache.me("marshalled_array") { expected_object }
22
16
 
23
17
  Marshal.load(Lawnchair.redis["Lawnchair:marshalled_array"]).should == [1,2,3,4]
24
18
  end
25
19
 
26
- describe "when passed :force => true" do
27
- it "expires the key and sets it to the new return value" do
28
- initial_expected_object = [1,2,3,4]
29
- new_expected_object = [1,2,3]
30
- Lawnchair::Cache.me(:key => "marshalled_array") { initial_expected_object }
31
- Marshal.load(Lawnchair.redis["Lawnchair:marshalled_array"]).should == [1,2,3,4]
32
-
33
- Lawnchair::Cache.me(:key => "marshalled_array", :force => true) { new_expected_object }
34
- Marshal.load(Lawnchair.redis["Lawnchair:marshalled_array"]).should == [1,2,3]
35
- end
36
- end
37
-
38
20
  describe "when in_process => true" do
39
- describe "when the value does not exist in redis" do
40
- it "should set the value to the key in process as well as in redis" do
41
- expected_object = [1,2,3,4]
42
- Lawnchair::Cache.me(:key => "marshalled_array", :in_process => true) { expected_object }
43
- Marshal.load(Lawnchair.redis["Lawnchair:marshalled_array"]).should == [1,2,3,4]
44
- Marshal.load(Lawnchair::Cache.in_process_store["Lawnchair:marshalled_array"]).should == [1,2,3,4]
45
- end
46
- end
47
-
48
- describe "when the value exists in redis" do
49
- it "takes the value from redis and places it in the in process cache" do
50
- Lawnchair::Cache.in_process_store.delete("Lawnchair:marshalled_array")
51
- expected_object = [1,2,3,4]
52
- unexpected_object = [1,2,3,4,5,6,7,8]
53
- Lawnchair::Cache.me(:key => "marshalled_array") { expected_object }
54
- Lawnchair::Cache.in_process_store["Lawnchair:marshalled_array"].should be_nil
55
- Lawnchair::Cache.me(:key => "marshalled_array", :in_process => true) { unexpected_object }
56
- Marshal.load(Lawnchair::Cache.in_process_store["Lawnchair:marshalled_array"]).should == expected_object
57
- end
21
+ it "fetches the value to/from the composite store" do
22
+ mock_composite_engine = Lawnchair::StorageEngine::Composite.new
23
+ Lawnchair::StorageEngine::Composite.stub!(:new).and_return(mock_composite_engine)
24
+
25
+ mock_composite_engine.should_receive(:fetch)
26
+ Lawnchair::Cache.me("mu", :in_process => true, :raw => true) { "fasa" }
58
27
  end
59
28
  end
60
-
61
- it "sets a default ttl of 60 minutes" do
62
- Lawnchair::Cache.me(:key => "pizza") { "muschroom/onion" }
63
- Lawnchair.redis.ttl("Lawnchair:pizza").should == 3600 # seconds
64
- end
65
-
66
- it "allows you to override the default ttl" do
67
- Lawnchair::Cache.me(:key => "pizza", :expires_in => 1) { "muschroom/onion" }
68
- Lawnchair.redis.ttl("Lawnchair:pizza").should == 1 # seconds
69
- end
70
- end
71
-
72
- describe ".exists?" do
73
- it "returns false when the key does not exist" do
74
- Lawnchair.redis.keys('*').should_not include("Lawnchair:mu")
75
- Lawnchair::Cache.exists?("mu").should be_false
76
- end
77
-
78
- it "returns true when the key exists" do
79
- Lawnchair.redis["Lawnchair:mu"] = "fasa"
80
- Lawnchair.redis.keys('*').should include("Lawnchair:mu")
81
- Lawnchair::Cache.exists?("mu").should be_true
82
- end
83
- end
84
-
85
- describe ".expire" do
86
- it "should only expire the key specified" do
87
- Lawnchair.redis["Lawnchair:mu"] = "fasa"
88
- Lawnchair.redis["Lawnchair:sim"] = "ba"
89
-
90
- Lawnchair::Cache.expire("mu")
91
- Lawnchair.redis["Lawnchair:mu"].should be_nil
92
- Lawnchair.redis["Lawnchair:sim"].should == "ba"
93
- end
94
29
  end
95
30
  end
data/spec/spec_helper.rb CHANGED
@@ -8,5 +8,12 @@ require 'redis'
8
8
 
9
9
  Spec::Runner.configure do |config|
10
10
  config.before(:all) { Lawnchair.connectdb(Redis.new(:db => 11)) }
11
- config.before(:each) { Lawnchair.flushdb }
11
+ config.before(:each) do
12
+ Lawnchair.flushdb
13
+ abstract_store = Lawnchair::StorageEngine::Abstract
14
+ abstract_store.cache_container.keys.each {|k| abstract_store.cache_container.delete(k)}
15
+
16
+ in_process = Lawnchair::StorageEngine::InProcess
17
+ in_process.cache_container.keys.each {|k| in_process.cache_container.delete(k)}
18
+ end
12
19
  end
@@ -0,0 +1,103 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Lawnchair::StorageEngine::Abstract" do
4
+ attr_reader :abstract_store
5
+
6
+ before do
7
+ @abstract_store = Lawnchair::StorageEngine::Abstract
8
+ end
9
+
10
+ describe ".cache_container" do
11
+ it "should be an empty hash" do
12
+ abstract_store.cache_container.should == {}
13
+ end
14
+ end
15
+
16
+ describe ".fetch" do
17
+ context "when key exists" do
18
+ before do
19
+ abstract_store.stub!(:exists?).and_return(true)
20
+ abstract_store.cache_container["Lawnchair:sim"] = "ba"
21
+ end
22
+
23
+ it "returns the value from the cache" do
24
+ value = abstract_store.fetch("sim", :raw => true) { "DOESNT MATTER" }
25
+ value.should == "ba"
26
+ end
27
+ end
28
+
29
+ context "when key does not exist" do
30
+ before do
31
+ abstract_store.stub!(:exists?).and_return(false)
32
+ abstract_store.cache_container["Lawnchair:sim"].should be_nil
33
+
34
+ class Lawnchair::StorageEngine::Abstract
35
+ def self.set(key, value, options={})
36
+ cache_container["Lawnchair:#{key}"] = value
37
+ end
38
+ end
39
+ end
40
+
41
+ it "computes the value and saves it to the cache" do
42
+ value = abstract_store.fetch("sim", :raw => true) { "ba" }
43
+ abstract_store.cache_container["Lawnchair:sim"].should == "ba"
44
+ end
45
+ end
46
+ end
47
+
48
+ describe ".get" do
49
+ context "when raw is true" do
50
+ it "gets the value in key if it exists" do
51
+ abstract_store.cache_container["Lawnchair:mu"] = "fasa"
52
+ abstract_store.get("mu", :raw => true).should == "fasa"
53
+ end
54
+
55
+ it "returns nil if the key does not exist" do
56
+ abstract_store.cache_container["mu"].should be_nil
57
+ abstract_store.get("mu", :raw => true).should be_nil
58
+ end
59
+ end
60
+
61
+ context "when raw is false" do
62
+ context "when they key exists" do
63
+ before do
64
+ abstract_store.stub!(:exists?).and_return(true)
65
+ end
66
+
67
+ it "gets the value in key if it exists and unmarshalls it" do
68
+ expected_value = "fasa"
69
+ value = Marshal.dump(expected_value)
70
+
71
+ abstract_store.cache_container["Lawnchair:mu"] = value
72
+ abstract_store.get("mu", :raw => false).should == expected_value
73
+ end
74
+ end
75
+
76
+ context "when the key does not exist" do
77
+ before do
78
+ abstract_store.stub!(:exists?).and_return(false)
79
+ end
80
+
81
+ it "returns nil if the key does not exist" do
82
+ abstract_store.cache_container["Lawnchair:mu"].should be_nil
83
+ abstract_store.get("mu", :raw => false).should be_nil
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ describe ".computed_key" do
90
+ it "should prepend keys with Lawnchair:" do
91
+ abstract_store.computed_key("hooo").should == "Lawnchair:hooo"
92
+ end
93
+ it "raises an exception if no key is given" do
94
+ lambda do
95
+ abstract_store.computed_key("") { 1 }
96
+ end.should raise_error
97
+
98
+ lambda do
99
+ abstract_store.computed_key(nil)
100
+ end.should raise_error
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,108 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Lawnchair::StorageEngine::Composite" do
4
+ attr_reader :composite_store
5
+
6
+ before do
7
+ @composite_store = Lawnchair::StorageEngine::Composite.new
8
+ end
9
+
10
+ describe "initialization" do
11
+ it "has a collection of storage_engines" do
12
+ composite_store.storage_engines == []
13
+ end
14
+ end
15
+
16
+ describe "#register_storage_engine" do
17
+ before do
18
+ composite_store.storage_engines.should be_empty
19
+ end
20
+
21
+ it "adds a storage engine to the collection" do
22
+ composite_store.register_storage_engine Lawnchair::StorageEngine::Redis
23
+ composite_store.storage_engines.should == [Lawnchair::StorageEngine::Redis]
24
+ end
25
+ end
26
+
27
+ describe "#fetch" do
28
+ context "when no storage engines have been configured" do
29
+ it "raises an exception" do
30
+ lambda do
31
+ composite_store.fetch("key", {}) {x=1}
32
+ end.should raise_error("No Storage Engines Configured")
33
+ end
34
+ end
35
+
36
+ context "when there is only 1 storage engine" do
37
+ before do
38
+ composite_store.register_storage_engine Lawnchair::StorageEngine::Redis
39
+ end
40
+
41
+ context "when the key does not exist" do
42
+ it "sets the value on the key in the storage engine specified" do
43
+ Lawnchair.redis["Lawnchair:mu"].should be_nil
44
+ composite_store.fetch("mu", {:raw => true}) { "fasa" }
45
+ Lawnchair.redis["Lawnchair:mu"].should == "fasa"
46
+ end
47
+ end
48
+
49
+ context "when the key exists" do
50
+ before do
51
+ Lawnchair.redis["Lawnchair:sim"] = "ba"
52
+ end
53
+
54
+ it "returns the value in the key from the storage engine specified" do
55
+ value = composite_store.fetch("sim", {:raw => true}) { "DOESNT MATTER" }
56
+ value.should == "ba"
57
+ end
58
+ end
59
+ end
60
+
61
+ context "when there are two storage engines" do
62
+ before do
63
+ composite_store.register_storage_engine Lawnchair::StorageEngine::InProcess
64
+ composite_store.register_storage_engine Lawnchair::StorageEngine::Redis
65
+ end
66
+
67
+ context "when the key exists in the first storage engine" do
68
+ before do
69
+ Lawnchair::StorageEngine::InProcess.set("mu", "fasa", :raw => true)
70
+ Lawnchair::StorageEngine::Redis.get("mu").should be_nil
71
+ end
72
+
73
+ it "returns the value from the first storage engine" do
74
+ value = composite_store.fetch("mu", {:raw => true}) { "DOESNT MATTER" }
75
+ value.should == "fasa"
76
+ end
77
+ end
78
+
79
+ context "when the key exists in the second storage engine but not the first" do
80
+ before do
81
+ Lawnchair::StorageEngine::InProcess.get("mu").should be_nil
82
+ Lawnchair::StorageEngine::Redis.set("mu", "fasa", :raw => true)
83
+ end
84
+
85
+ it "places the value in the first storage engine" do
86
+ composite_store.fetch("mu", {:raw => true}) { "DOESNT MATTER" }.should == "fasa"
87
+ Lawnchair::StorageEngine::InProcess.get("mu", :raw => true).should == "fasa"
88
+ end
89
+ end
90
+
91
+ context "when the key doesnt exist in either storage engine" do
92
+ before do
93
+ Lawnchair::StorageEngine::InProcess.get("mu").should be_nil
94
+ Lawnchair::StorageEngine::Redis.get("mu").should be_nil
95
+ end
96
+
97
+ it "sets the value in both storage engines" do
98
+ composite_store.fetch("mu", {:raw => true}) { sleep 0.2; "fasa" }
99
+ Lawnchair::StorageEngine::InProcess.get("mu", :raw => true).should == "fasa"
100
+ Lawnchair::StorageEngine::Redis.get("mu", :raw => true).should == "fasa"
101
+ end
102
+
103
+ it "only calls the block 1 time for both engines" # spec should take less than .4 seconds to run
104
+ end
105
+ end
106
+ end
107
+
108
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Lawnchair::StorageEngine::InProcessStore" do
4
+ attr_reader :in_process_store
5
+
6
+ before do
7
+ @in_process_store = Lawnchair::StorageEngine::InProcess
8
+ end
9
+
10
+ describe "#cache_container" do
11
+ it "returns the redis cache object" do
12
+ Lawnchair::StorageEngine::InProcess.send(:class_variable_set, "@@cache_container", {"Lawnchair:mu" => "fasa"})
13
+ in_process_store.cache_container["Lawnchair:mu"].should == "fasa"
14
+ end
15
+ end
16
+
17
+ describe "#set" do
18
+ context "when raw is true" do
19
+ it "sets the value" do
20
+ in_process_store.cache_container["Lawnchair:mu"].should be_nil
21
+ in_process_store.set("mu", "fasa", :raw => true)
22
+ in_process_store.cache_container["Lawnchair:mu"].should == "fasa"
23
+ end
24
+ end
25
+
26
+ context "when raw is false" do
27
+ it "sets the value" do
28
+ value = "fasa"
29
+ expected_value = Marshal.dump(value)
30
+
31
+ in_process_store.cache_container["Lawnchair:mu"].should be_nil
32
+ in_process_store.set("mu", value, :raw => false)
33
+ in_process_store.cache_container["Lawnchair:mu"].should == expected_value
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "exists?" do
39
+ it "returns false when the key does not exist" do
40
+ in_process_store.cache_container.keys.should_not include("Lawnchair:mu")
41
+ in_process_store.exists?("mu").should be_false
42
+ end
43
+
44
+ it "returns true when the key exists" do
45
+ in_process_store.cache_container["Lawnchair:mu"] = "fasa"
46
+ in_process_store.cache_container.keys.should include("Lawnchair:mu")
47
+ in_process_store.exists?("mu").should be_true
48
+ end
49
+ end
50
+
51
+ describe "#expire!" do
52
+ it "should only expire the key specified" do
53
+ in_process_store.cache_container["Lawnchair:mu"] = "fasa"
54
+ in_process_store.cache_container["Lawnchair:sim"] = "ba"
55
+
56
+ in_process_store.expire!("mu")
57
+ in_process_store.cache_container["Lawnchair:mu"].should be_nil
58
+ in_process_store.cache_container["Lawnchair:sim"].should == "ba"
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,72 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Lawnchair::StorageEngine::RedisStore" do
4
+ attr_reader :redis_store
5
+
6
+ before do
7
+ @redis_store = Lawnchair::StorageEngine::Redis
8
+ end
9
+
10
+ describe "#cache_container" do
11
+ it "returns the redis cache object" do
12
+ Lawnchair.redis["Lawnchair:mu"] = "fasa"
13
+ redis_store.cache_container["Lawnchair:mu"].should == "fasa"
14
+ end
15
+ end
16
+
17
+ describe "#set" do
18
+ it "sets a default ttl of 60 minutes" do
19
+ redis_store.set("mu", "fasa")
20
+ Lawnchair.redis.ttl("Lawnchair:mu").should == 3600 # seconds
21
+ end
22
+
23
+ it "allows you to override the default ttl" do
24
+ redis_store.set("mu", "fasa", :expires_in => 600)
25
+
26
+ Lawnchair.redis.ttl("Lawnchair:mu").should == 600 # seconds
27
+ end
28
+
29
+ context "when raw is true" do
30
+ it "sets the value in redis" do
31
+ Lawnchair.redis["Lawnchair:mu"].should be_nil
32
+ redis_store.set("mu", "fasa", :raw => true)
33
+ Lawnchair.redis["Lawnchair:mu"].should == "fasa"
34
+ end
35
+ end
36
+
37
+ context "when raw is false" do
38
+ it "sets the value in redis" do
39
+ value = "fasa"
40
+ expected_value = Marshal.dump(value)
41
+
42
+ Lawnchair.redis["Lawnchair:mu"].should be_nil
43
+ redis_store.set("mu", value, :raw => false)
44
+ Lawnchair.redis["Lawnchair:mu"].should == expected_value
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "exists?" do
50
+ it "returns false when the key does not exist" do
51
+ Lawnchair.redis.keys('*').should_not include("Lawnchair:mu")
52
+ redis_store.exists?("mu").should be_false
53
+ end
54
+
55
+ it "returns true when the key exists" do
56
+ Lawnchair.redis["Lawnchair:mu"] = "fasa"
57
+ Lawnchair.redis.keys('*').should include("Lawnchair:mu")
58
+ redis_store.exists?("mu").should be_true
59
+ end
60
+ end
61
+
62
+ describe "#expire!" do
63
+ it "should only expire the key specified" do
64
+ Lawnchair.redis["Lawnchair:mu"] = "fasa"
65
+ Lawnchair.redis["Lawnchair:sim"] = "ba"
66
+
67
+ redis_store.expire!("mu")
68
+ Lawnchair.redis["Lawnchair:mu"].should be_nil
69
+ Lawnchair.redis["Lawnchair:sim"].should == "ba"
70
+ end
71
+ end
72
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lawnchair
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane Wolf
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-11 00:00:00 -08:00
12
+ date: 2010-02-12 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -30,11 +30,20 @@ files:
30
30
  - VERSION
31
31
  - lawnchair.gemspec
32
32
  - lib/lawnchair.rb
33
+ - lib/storage_engine/abstract.rb
34
+ - lib/storage_engine/composite.rb
35
+ - lib/storage_engine/in_process.rb
36
+ - lib/storage_engine/redis.rb
37
+ - lib/view/helper.rb
33
38
  - spec/lawnchair_spec.rb
34
39
  - spec/spec.opts
35
40
  - spec/spec_helper.rb
36
41
  - spec/speed.rb
37
42
  - spec/speed_results.png
43
+ - spec/storage_engine/abstract_spec.rb
44
+ - spec/storage_engine/composite_spec.rb
45
+ - spec/storage_engine/in_process_spec.rb
46
+ - spec/storage_engine/redis_spec.rb
38
47
  has_rdoc: true
39
48
  homepage: http://github.com/gizm0duck/lawnchair
40
49
  licenses: []
@@ -67,3 +76,7 @@ test_files:
67
76
  - spec/lawnchair_spec.rb
68
77
  - spec/spec_helper.rb
69
78
  - spec/speed.rb
79
+ - spec/storage_engine/abstract_spec.rb
80
+ - spec/storage_engine/composite_spec.rb
81
+ - spec/storage_engine/in_process_spec.rb
82
+ - spec/storage_engine/redis_spec.rb