that_old_cache 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,16 @@
1
+ That Old Cache
2
+ ==============
3
+
4
+ Description
5
+ -----------
6
+
7
+ Getting sick of memcached just kicking your stuff out of memory in Rails? Maybe you've thought
8
+ *"Gee, wouldn't it be nice to just serve the old cache while I refresh it."* Well, look no
9
+ further! **That Old Cache** is a Rubygem that does just that, giving you the ability to fire
10
+ off a process to refresh the cache once it expires, without the annoying "initial load" problem
11
+ that affects your users.
12
+
13
+ Authors
14
+ -------
15
+
16
+ Joey Robert ([http://joeyrobert.org/](http://joeyrobert.org/))
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/gempackagetask'
4
+ require 'spec/rake/spectask'
5
+
6
+ desc 'Default: run specs.'
7
+ task :default => :spec
8
+
9
+ desc 'Run the specs'
10
+ Spec::Rake::SpecTask.new(:spec) do |t|
11
+ t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
12
+ t.spec_files = FileList['spec/**/*_spec.rb']
13
+ end
14
+
15
+ PKG_FILES = FileList['lib/**/*', 'spec/*', 'Rakefile', 'README.md', 'VERSION']
16
+
17
+ spec = Gem::Specification.new do |s|
18
+ s.name = "that_old_cache"
19
+ s.version = "0.0.1"
20
+ s.author = "Joey Robert"
21
+ s.email = "joey@joeyrobert.org"
22
+ s.homepage = "http://github.com/joeyrobert/that_old_cache"
23
+ s.platform = Gem::Platform::RUBY
24
+ s.summary = "Serve old caches from memcached while you update in Rails"
25
+ s.description = "An ActiveSupport MemCache store that requires serves keys until they are explicitly overwritten"
26
+ s.files = PKG_FILES.to_a
27
+ s.require_path = "lib"
28
+ s.has_rdoc = false
29
+ s.add_dependency "yajl-ruby", ">= 0.7.x"
30
+ s.add_dependency "activesupport", ">= 2.3.x"
31
+ end
32
+
33
+ desc 'Turn this plugin into a gem.'
34
+ Rake::GemPackageTask.new(spec) { |pkg| pkg.gem_spec = spec }
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1 @@
1
+ require 'that_old_cache/ttled_mem_cache_store'
@@ -0,0 +1,60 @@
1
+ require 'active_support'
2
+ require 'yajl'
3
+
4
+ module ActiveSupport
5
+ module Cache
6
+ class TTLedMemCacheStore < MemCacheStore
7
+ # Adds the following option:
8
+ # :valid_for => number of seconds from now that the cache with "expire"
9
+ # :raw is not supported with :valid_for
10
+ def write(key, value, options = nil)
11
+ if options && options[:valid_for]
12
+ options.delete(:raw)
13
+ super(key, encode({ :data => value, :ttl => time_for(options.delete(:valid_for)) }), options)
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ # Adds the following option:
20
+ # :valid_for => true
21
+ # :raw is not supported with :valid_for
22
+ def read(key, options = nil)
23
+ if options && options.delete(:valid_for)
24
+ options.delete(:raw)
25
+ parse(super)[:data] rescue nil
26
+ else
27
+ super
28
+ end
29
+ end
30
+
31
+ # only works for TTLed keys
32
+ def expired?(key)
33
+ begin
34
+ ttl(key) < Time.now.to_i
35
+ rescue NoMethodError
36
+ false
37
+ end
38
+ end
39
+
40
+ # only works for TTLed keys
41
+ def ttl(key)
42
+ parse(read(key))[:ttl] rescue nil
43
+ end
44
+
45
+ private
46
+
47
+ def time_for(seconds)
48
+ Time.now.to_i + seconds.to_i
49
+ end
50
+
51
+ def parse(val)
52
+ Yajl::Parser.new(:symbolize_keys => true).parse(val)
53
+ end
54
+
55
+ def encode(val)
56
+ Yajl::Encoder.encode(val)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,2 @@
1
+ require "spec"
2
+ require File.dirname(__FILE__) + '/../lib/that_old_cache'
@@ -0,0 +1,79 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe ActiveSupport::Cache::TTLedMemCacheStore do
4
+ # Since this is about interface to a cache, I think it makes sense to run a
5
+ # real cache in this case and not mock/stub it out. TODO: Rake to start/detach
6
+ # a memcached?
7
+ before(:all) do
8
+ begin
9
+ # Run on non-default port so not to accidentally mess with a real cache
10
+ @cache = ActiveSupport::Cache::TTLedMemCacheStore.new("127.0.0.1:12345")
11
+ # Call to make sure we have a live connection
12
+ @cache.exist?("cache_key")
13
+ rescue => e
14
+ $stderr.puts e.message
15
+ $stderr.puts "Make sure memcached is listening on tcpport 12345: /path/to/memcached -p 12345"
16
+ exit
17
+ end
18
+
19
+ @key = "example_key"
20
+ @value = "example_value"
21
+ end
22
+
23
+ after(:each) do
24
+ @cache.clear
25
+ end
26
+
27
+ context "ttl'd keys" do
28
+ before(:each) do
29
+ @valid_for = 10
30
+ @cache.write(@key, @value, :valid_for => @valid_for)
31
+ end
32
+
33
+ it "should set the expected value in the cache" do
34
+ @cache.read(@key, :valid_for => true).should == @value
35
+ end
36
+
37
+ it "should have the proper ttl" do
38
+ @cache.ttl(@key).should be_close(Time.now.to_i + @valid_for, 1)
39
+ end
40
+
41
+ # Vendor something to time_travel if this sleep stuff gets annoying
42
+ it "should be expired if the ttl is less than now" do
43
+ @cache.write(@key, @value, :valid_for => 0.1)
44
+ sleep 1
45
+ @cache.expired?(@key).should be_true
46
+ end
47
+
48
+ it "should not be expired if the ttl is greater than now" do
49
+ @cache.write(@key, @value, :valid_for => 5)
50
+ @cache.expired?(@key).should be_false
51
+ end
52
+ end
53
+
54
+ context "non-ttl'd keys" do
55
+ before(:each) do
56
+ @cache.write(@key, @value)
57
+ end
58
+
59
+ it "should set the non-serialized value in the cache" do
60
+ @cache.read(@key).should == @value
61
+ end
62
+
63
+ it "should have a nil ttl" do
64
+ @cache.ttl(@key).should be_nil
65
+ end
66
+
67
+ it "should not be expired" do
68
+ @cache.expired?(@key).should be_false
69
+ end
70
+
71
+ it "should not raise an exception if trying a ttl'd read on a non-ttl'd key" do
72
+ lambda { @cache.read(@key, :valid_for => true) }.should_not raise_error
73
+ end
74
+
75
+ it "should return nil if trying a ttl'd read on a non-ttl'd key" do
76
+ @cache.read(@key, :valid_for => true).should be_nil
77
+ end
78
+ end
79
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: that_old_cache
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Joey Robert
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-13 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: yajl-ruby
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 7
30
+ - x
31
+ version: 0.7.x
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: activesupport
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 2
43
+ - 3
44
+ - x
45
+ version: 2.3.x
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ description: An ActiveSupport MemCache store that requires serves keys until they are explicitly overwritten
49
+ email: joey@joeyrobert.org
50
+ executables: []
51
+
52
+ extensions: []
53
+
54
+ extra_rdoc_files: []
55
+
56
+ files:
57
+ - lib/that_old_cache.rb
58
+ - lib/that_old_cache/ttled_mem_cache_store.rb
59
+ - spec/spec_helper.rb
60
+ - spec/that_old_cache_spec.rb
61
+ - Rakefile
62
+ - README.md
63
+ - VERSION
64
+ has_rdoc: true
65
+ homepage: http://github.com/joeyrobert/that_old_cache
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options: []
70
+
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ requirements: []
88
+
89
+ rubyforge_project:
90
+ rubygems_version: 1.3.6
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Serve old caches from memcached while you update in Rails
94
+ test_files: []
95
+