cache_method 0.0.1 → 0.0.2

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/.gitignore CHANGED
@@ -3,3 +3,5 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  rdoc/*
6
+ secret.sh
7
+ .DS_Store
data/README.rdoc CHANGED
@@ -42,17 +42,17 @@ And clear them too
42
42
 
43
43
  == Configuration (and supported cache clients)
44
44
 
45
- You need to set a client that will be used to access the cache:
45
+ You need to set where the cache will be stored:
46
46
 
47
- CacheMethod.config.client = Memcached.new '127.0.0.1:11211'
47
+ CacheMethod.config.storage = Memcached.new '127.0.0.1:11211'
48
48
 
49
49
  or
50
50
 
51
- CacheMethod.config.client = Redis.new
51
+ CacheMethod.config.storage = Redis.new
52
52
 
53
53
  or this might even work...
54
54
 
55
- CacheMethod.config.client = Rails.cache
55
+ CacheMethod.config.storage = Rails.cache
56
56
 
57
57
  See <tt>Config</tt> for the full list of supported caches.
58
58
 
data/cache_method.gemspec CHANGED
@@ -8,9 +8,9 @@ Gem::Specification.new do |s|
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Seamus Abshere"]
10
10
  s.email = ["seamus@abshere.net"]
11
- s.homepage = ""
12
- s.summary = %q{Provides cache_method}
13
- s.description = %q{Lets you cache methods (to memcached, redis, etc.) sort of like you can memoize them}
11
+ s.homepage = "https://github.com/seamusabshere/cache_method"
12
+ s.summary = %q{Lets you cache methods (to memcached, redis, etc.) sort of like you can memoize them}
13
+ s.description = %q{Like alias_method, but it's cache_method!}
14
14
 
15
15
  s.rubyforge_project = "cache_method"
16
16
 
@@ -18,13 +18,8 @@ Gem::Specification.new do |s|
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.add_development_dependency 'redis'
22
- s.add_development_dependency 'activesupport', '>=2.3.4'
23
- s.add_development_dependency 'i18n' # activesupport
24
- s.add_development_dependency 'test-unit'
21
+ s.add_dependency 'cache'
25
22
  s.add_development_dependency 'memcached'
26
- s.add_development_dependency 'dalli'
27
- s.add_development_dependency 'memcache-client'
28
23
  # if RUBY_VERSION >= '1.9'
29
24
  # s.add_development_dependency 'ruby-debug19'
30
25
  # else
@@ -0,0 +1,56 @@
1
+ require 'digest/md5'
2
+ module CacheMethod
3
+ class CachedResult #:nodoc: all
4
+ class << self
5
+ def fetch(options = {})
6
+ cached_result = new options
7
+ cached_result.fetch
8
+ end
9
+ end
10
+
11
+ def initialize(options = {})
12
+ options.each do |k, v|
13
+ instance_variable_set "@#{k}", v
14
+ end
15
+ end
16
+
17
+ attr_reader :obj
18
+ attr_reader :method_id
19
+ attr_reader :original_method_id
20
+ attr_reader :args
21
+
22
+ def fetch
23
+ if v = Config.instance.storage.get(cache_key) and v.is_a?(::Array)
24
+ v[0]
25
+ else
26
+ v = obj.send original_method_id, *args
27
+ Config.instance.storage.set cache_key, [v], ttl
28
+ v
29
+ end
30
+ end
31
+
32
+ def ttl
33
+ @ttl ||= Config.instance.default_ttl
34
+ end
35
+
36
+ def cache_key
37
+ [ method_signature, current_epoch, obj_hash, args_digest ].join ','
38
+ end
39
+
40
+ def method_signature
41
+ @method_signature ||= ::CacheMethod.method_signature(obj, method_id)
42
+ end
43
+
44
+ def obj_hash
45
+ @obj_hash ||= obj.hash
46
+ end
47
+
48
+ def args_digest
49
+ @args_digest ||= ::Digest::MD5.hexdigest(args.flatten.join)
50
+ end
51
+
52
+ def current_epoch
53
+ @current_epoch ||= Epoch.current(:obj => obj, :method_id => method_id)
54
+ end
55
+ end
56
+ end
@@ -1,16 +1,17 @@
1
+ require 'cache'
1
2
  require 'singleton'
2
3
  module CacheMethod
3
4
  # Here's where you set config options.
4
5
  #
5
6
  # Example:
6
- # CacheMethod.config.client = Memcached.new '127.0.0.1:11211'
7
+ # CacheMethod.config.storage = Memcached.new '127.0.0.1:11211'
7
8
  # CacheMethod.config.default_ttl = 120 # seconds
8
9
  #
9
10
  # You'd probably put this in your Rails config/initializers, for example.
10
11
  class Config
11
12
  include ::Singleton
12
13
 
13
- # Client for accessing the cache.
14
+ # Storage for the cache.
14
15
  #
15
16
  # Supported memcached clients:
16
17
  # * memcached[https://github.com/fauna/memcached] (either a Memcached or a Memcached::Rails)
@@ -18,16 +19,18 @@ module CacheMethod
18
19
  # * memcache-client[https://github.com/mperham/memcache-client] (MemCache, the one commonly used by Rails)
19
20
  #
20
21
  # Supported Redis clients:
21
- # * redis[https://github.com/ezmobius/redis-rb] (NOTE: AUTOMATIC CACHE EXPIRATION NOT SUPPORTED)
22
+ # * redis[https://github.com/ezmobius/redis-rb]
23
+ #
24
+ # Uses the cache[https://github.com/seamusabshere/cache] gem to wrap these, so support depends on that gem
22
25
  #
23
26
  # Example:
24
- # CacheMethod.config.client = Memcached.new '127.0.0.1:11211'
25
- def client=(client)
26
- @client = client
27
+ # CacheMethod.config.storage = Memcached.new '127.0.0.1:11211'
28
+ def storage=(raw_client)
29
+ @storage = ::Cache.new raw_client
27
30
  end
28
31
 
29
- def client #:nodoc:
30
- @client || raise("You need to set CacheMethod.config.client with a cache client of your choice")
32
+ def storage #:nodoc:
33
+ @storage || raise("You need to set CacheMethod.config.storage with a cache storage of your choice")
31
34
  end
32
35
 
33
36
  # TTL for method caches. Defaults to 60 seconds.
@@ -0,0 +1,44 @@
1
+ module CacheMethod
2
+ class Epoch #:nodoc: all
3
+ class << self
4
+ def current(options = {})
5
+ epoch = new options
6
+ epoch.current
7
+ end
8
+
9
+ def mark_passing(options = {})
10
+ epoch = new options
11
+ epoch.mark_passing
12
+ end
13
+ end
14
+
15
+ def initialize(options = {})
16
+ options.each do |k, v|
17
+ instance_variable_set "@#{k}", v
18
+ end
19
+ end
20
+
21
+ attr_reader :obj
22
+ attr_reader :method_id
23
+
24
+ def method_signature
25
+ @method_signature ||= ::CacheMethod.method_signature(obj, method_id)
26
+ end
27
+
28
+ def obj_hash
29
+ @obj_hash ||= obj.hash
30
+ end
31
+
32
+ def cache_key
33
+ [ 'CacheMethod', method_signature, obj_hash ].join ','
34
+ end
35
+
36
+ def current
37
+ Config.instance.storage.get(cache_key).to_i
38
+ end
39
+
40
+ def mark_passing
41
+ Config.instance.storage.set cache_key, (current+1), 0
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
1
  module CacheMethod
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/cache_method.rb CHANGED
@@ -1,14 +1,24 @@
1
+ require 'cache_method/version'
1
2
  # See the README.rdoc for more info!
2
3
  module CacheMethod
3
4
  autoload :Config, 'cache_method/config'
4
- autoload :Cache, 'cache_method/cache'
5
+ autoload :CachedResult, 'cache_method/cached_result'
6
+ autoload :Epoch, 'cache_method/epoch'
5
7
 
6
8
  def self.config #:nodoc:
7
9
  Config.instance
8
10
  end
9
11
 
10
- def self.cache #:nodoc:
11
- Cache.instance
12
+ def self.klass_name(obj) #:nodoc:
13
+ obj.is_a?(::Class) ? obj.to_s : obj.class.to_s
14
+ end
15
+
16
+ def self.method_delimiter(obj) #:nodoc:
17
+ obj.is_a?(::Class) ? '.' : '#'
18
+ end
19
+
20
+ def self.method_signature(obj, method_id) #:nodoc:
21
+ [ klass_name(obj), method_id ].join method_delimiter(obj)
12
22
  end
13
23
 
14
24
  # All Objects, including instances and Classes, get the <tt>#clear_method_cache</tt> method.
@@ -20,7 +30,7 @@ module CacheMethod
20
30
  # Example:
21
31
  # my_blog.clear_method_cache :get_latest_entries
22
32
  def clear_method_cache(method_id)
23
- ::CacheMethod.cache.delete self, method_id
33
+ ::CacheMethod::Epoch.mark_passing :obj => self, :method_id => method_id
24
34
  end
25
35
  end
26
36
 
@@ -47,9 +57,7 @@ module CacheMethod
47
57
  original_method_id = "_uncached_#{method_id}"
48
58
  alias_method original_method_id, method_id
49
59
  define_method method_id do |*args|
50
- ::CacheMethod.cache.fetch self, method_id, ttl, *args do
51
- send original_method_id, *args
52
- end
60
+ ::CacheMethod::CachedResult.fetch :obj => self, :method_id => method_id, :original_method_id => original_method_id, :args => args, :ttl => ttl
53
61
  end
54
62
  end
55
63
  end
data/test/helper.rb CHANGED
@@ -8,44 +8,50 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
8
  require 'cache_method'
9
9
 
10
10
  class Test::Unit::TestCase
11
- def setup
12
- CacheMethod.cache.flush
13
- end
14
11
  end
15
12
 
16
- require 'memcached'
17
- require 'memcache'
18
- require 'redis'
19
- require 'dalli'
20
- require 'active_support/all'
21
- require 'active_support/cache/dalli_store'
22
- def random_cache
23
- c = if ENV['C']
24
- ENV['C'].to_i
25
- else
26
- rand 6
13
+ class Blog1
14
+ attr_reader :name
15
+ attr_reader :url
16
+ def initialize(name, url)
17
+ @name = name
18
+ @url = url
19
+ end
20
+ attr_writer :request_count
21
+ def request_count
22
+ @request_count ||= 0
23
+ end
24
+ def get_latest_entries
25
+ self.request_count += 1
26
+ ["hello from #{name}"]
27
+ end
28
+ cache_method :get_latest_entries
29
+ def get_latest_entries2
30
+ self.request_count += 1
31
+ ["voo vaa #{name}"]
27
32
  end
28
- case c
29
- when 0
30
- $stderr.puts 'using memcached'
31
- Memcached.new 'localhost:11211'
32
- when 1
33
- $stderr.puts 'using memcache-client'
34
- MemCache.new ['localhost:11211']
35
- when 2
36
- $stderr.puts 'using dalli'
37
- Dalli::Client.new ['localhost:11211']
38
- when 3
39
- $stderr.puts 'using dalli_store'
40
- ActiveSupport::Cache::DalliStore.new ['localhost:11211']
41
- when 4
42
- $stderr.puts 'using memcached-rails'
43
- Memcached::Rails.new 'localhost:11211'
44
- when 5
45
- $stderr.puts 'using Redis'
46
- Redis.new
33
+ cache_method :get_latest_entries2, 1 # second
34
+ def hash
35
+ { :name => name, :url => url }.hash
47
36
  end
48
37
  end
38
+ def new_instance_of_my_blog
39
+ Blog1.new 'my_blog', 'http://my_blog.example.com'
40
+ end
41
+ def new_instance_of_another_blog
42
+ Blog1.new 'another_blog', 'http://another_blog.example.com'
43
+ end
49
44
 
50
- $my_cache = random_cache
51
- CacheMethod.config.client = $my_cache
45
+ class Blog2
46
+ class << self
47
+ attr_writer :request_count
48
+ def request_count
49
+ @request_count ||= 0
50
+ end
51
+ def get_latest_entries
52
+ self.request_count += 1
53
+ 'danke schoen'
54
+ end
55
+ cache_method :get_latest_entries
56
+ end
57
+ end
@@ -1,40 +1,16 @@
1
1
  require 'helper'
2
2
 
3
- class Blog1
4
- attr_reader :name
5
- attr_reader :url
6
- def initialize(name, url)
7
- @name = name
8
- @url = url
9
- end
10
- attr_writer :request_count
11
- def request_count
12
- @request_count ||= 0
13
- end
14
- def get_latest_entries
15
- self.request_count += 1
16
- ["hello from #{name}"]
17
- end
18
- cache_method :get_latest_entries
19
- def get_latest_entries2
20
- self.request_count += 1
21
- ["voo vaa #{name}"]
22
- end
23
- cache_method :get_latest_entries2, 1 # second
24
- def hash
25
- { :name => name, :url => url }.hash
26
- end
27
- end
3
+ require 'memcached'
28
4
 
29
- class TestCacheInstanceMethods < Test::Unit::TestCase
30
- def new_instance_of_my_blog
31
- Blog1.new 'my_blog', 'http://my_blog.example.com'
32
- end
33
- def new_instance_of_another_blog
34
- Blog1.new 'another_blog', 'http://another_blog.example.com'
5
+ class TestCacheMethod < Test::Unit::TestCase
6
+ def setup
7
+ Blog2.request_count = 0
8
+ my_cache = Memcached.new '127.0.0.1:11211'
9
+ CacheMethod.config.storage = my_cache
10
+ my_cache.flush
35
11
  end
36
12
 
37
- def test_cache_method
13
+ def test_cache_instance_method
38
14
  a = new_instance_of_my_blog
39
15
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
40
16
  assert_equal 1, a.request_count
@@ -46,7 +22,7 @@ class TestCacheInstanceMethods < Test::Unit::TestCase
46
22
  assert_equal 1, xxx.request_count
47
23
  end
48
24
 
49
- def test_clear_method
25
+ def test_clear_instance_method
50
26
  a = new_instance_of_my_blog
51
27
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
52
28
  assert_equal 1, a.request_count
@@ -55,7 +31,7 @@ class TestCacheInstanceMethods < Test::Unit::TestCase
55
31
  assert_equal 2, a.request_count
56
32
  end
57
33
 
58
- def test_clear_a_different_method
34
+ def test_clear_correct_instance_method
59
35
  a = new_instance_of_my_blog
60
36
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
61
37
  assert_equal 1, a.request_count
@@ -64,7 +40,7 @@ class TestCacheInstanceMethods < Test::Unit::TestCase
64
40
  assert_equal 1, a.request_count
65
41
  end
66
42
 
67
- def test_clear_from_somebody_else
43
+ def test_clear_instance_method_from_correct_instance
68
44
  a = new_instance_of_my_blog
69
45
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
70
46
  assert_equal 1, a.request_count
@@ -78,13 +54,43 @@ class TestCacheInstanceMethods < Test::Unit::TestCase
78
54
  assert_equal 2, xxx.request_count
79
55
  end
80
56
 
81
- def test_ttl
57
+ def test_cache_instance_method_ttl
82
58
  a = new_instance_of_my_blog
83
59
  assert_equal ["voo vaa #{a.name}"], a.get_latest_entries2
84
60
  assert_equal 1, a.request_count
85
- a = new_instance_of_my_blog
86
61
  sleep 2
87
62
  assert_equal ["voo vaa #{a.name}"], a.get_latest_entries2
88
- assert_equal 1, a.request_count
63
+ assert_equal 2, a.request_count
64
+ end
65
+
66
+ def test_cache_class_method
67
+ assert_equal 0, Blog2.request_count
68
+ assert_equal 'danke schoen', Blog2.get_latest_entries
69
+ assert_equal 1, Blog2.request_count
70
+ assert_equal 'danke schoen', Blog2.get_latest_entries
71
+ assert_equal 1, Blog2.request_count
72
+ end
73
+
74
+ def test_clear_class_method
75
+ assert_equal 0, Blog2.request_count
76
+ assert_equal 'danke schoen', Blog2.get_latest_entries
77
+ assert_equal 1, Blog2.request_count
78
+ Blog2.clear_method_cache :get_latest_entries
79
+ assert_equal 'danke schoen', Blog2.get_latest_entries
80
+ assert_equal 2, Blog2.request_count
81
+ end
82
+
83
+ def test_clear_correct_class_method
84
+ assert_equal 0, Blog2.request_count
85
+ assert_equal 'danke schoen', Blog2.get_latest_entries
86
+ assert_equal 1, Blog2.request_count
87
+
88
+ Blog2.clear_method_cache :foobar
89
+ assert_equal 'danke schoen', Blog2.get_latest_entries
90
+ assert_equal 1, Blog2.request_count
91
+
92
+ Blog2.clear_method_cache :get_latest_entries
93
+ assert_equal 'danke schoen', Blog2.get_latest_entries
94
+ assert_equal 2, Blog2.request_count
89
95
  end
90
96
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cache_method
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Seamus Abshere
@@ -15,11 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-15 00:00:00 -06:00
18
+ date: 2011-02-17 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: redis
22
+ name: cache
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
@@ -30,84 +30,12 @@ dependencies:
30
30
  segments:
31
31
  - 0
32
32
  version: "0"
33
- type: :development
33
+ type: :runtime
34
34
  version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: activesupport
37
- prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 11
44
- segments:
45
- - 2
46
- - 3
47
- - 4
48
- version: 2.3.4
49
- type: :development
50
- version_requirements: *id002
51
- - !ruby/object:Gem::Dependency
52
- name: i18n
53
- prerelease: false
54
- requirement: &id003 !ruby/object:Gem::Requirement
55
- none: false
56
- requirements:
57
- - - ">="
58
- - !ruby/object:Gem::Version
59
- hash: 3
60
- segments:
61
- - 0
62
- version: "0"
63
- type: :development
64
- version_requirements: *id003
65
- - !ruby/object:Gem::Dependency
66
- name: test-unit
67
- prerelease: false
68
- requirement: &id004 !ruby/object:Gem::Requirement
69
- none: false
70
- requirements:
71
- - - ">="
72
- - !ruby/object:Gem::Version
73
- hash: 3
74
- segments:
75
- - 0
76
- version: "0"
77
- type: :development
78
- version_requirements: *id004
79
35
  - !ruby/object:Gem::Dependency
80
36
  name: memcached
81
37
  prerelease: false
82
- requirement: &id005 !ruby/object:Gem::Requirement
83
- none: false
84
- requirements:
85
- - - ">="
86
- - !ruby/object:Gem::Version
87
- hash: 3
88
- segments:
89
- - 0
90
- version: "0"
91
- type: :development
92
- version_requirements: *id005
93
- - !ruby/object:Gem::Dependency
94
- name: dalli
95
- prerelease: false
96
- requirement: &id006 !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ">="
100
- - !ruby/object:Gem::Version
101
- hash: 3
102
- segments:
103
- - 0
104
- version: "0"
105
- type: :development
106
- version_requirements: *id006
107
- - !ruby/object:Gem::Dependency
108
- name: memcache-client
109
- prerelease: false
110
- requirement: &id007 !ruby/object:Gem::Requirement
38
+ requirement: &id002 !ruby/object:Gem::Requirement
111
39
  none: false
112
40
  requirements:
113
41
  - - ">="
@@ -117,8 +45,8 @@ dependencies:
117
45
  - 0
118
46
  version: "0"
119
47
  type: :development
120
- version_requirements: *id007
121
- description: Lets you cache methods (to memcached, redis, etc.) sort of like you can memoize them
48
+ version_requirements: *id002
49
+ description: Like alias_method, but it's cache_method!
122
50
  email:
123
51
  - seamus@abshere.net
124
52
  executables: []
@@ -129,22 +57,19 @@ extra_rdoc_files: []
129
57
 
130
58
  files:
131
59
  - .gitignore
132
- - DEVELOPER_NOTES.rdoc
133
60
  - Gemfile
134
61
  - README.rdoc
135
62
  - Rakefile
136
63
  - cache_method.gemspec
137
64
  - lib/cache_method.rb
138
- - lib/cache_method/cache.rb
139
- - lib/cache_method/cache/epoch.rb
140
- - lib/cache_method/cache/key.rb
65
+ - lib/cache_method/cached_result.rb
141
66
  - lib/cache_method/config.rb
67
+ - lib/cache_method/epoch.rb
142
68
  - lib/cache_method/version.rb
143
69
  - test/helper.rb
144
- - test/test_cache_class_methods.rb
145
- - test/test_cache_instance_methods.rb
70
+ - test/test_cache_method.rb
146
71
  has_rdoc: true
147
- homepage: ""
72
+ homepage: https://github.com/seamusabshere/cache_method
148
73
  licenses: []
149
74
 
150
75
  post_install_message:
@@ -176,8 +101,7 @@ rubyforge_project: cache_method
176
101
  rubygems_version: 1.3.7
177
102
  signing_key:
178
103
  specification_version: 3
179
- summary: Provides cache_method
104
+ summary: Lets you cache methods (to memcached, redis, etc.) sort of like you can memoize them
180
105
  test_files:
181
106
  - test/helper.rb
182
- - test/test_cache_class_methods.rb
183
- - test/test_cache_instance_methods.rb
107
+ - test/test_cache_method.rb
data/DEVELOPER_NOTES.rdoc DELETED
@@ -1,45 +0,0 @@
1
- = Developer notes
2
-
3
- == Lots of cache method signatures...
4
-
5
- def get(k)
6
- if defined?(::Memcached) and raw_client.is_a?(::Memcached)
7
- # def get(keys, marshal=true)
8
- begin; raw_client.get(k.to_s); rescue ::Memcached::NotFound; nil; end
9
- elsif defined?(::Memcached::Rails) and raw_client.is_a?(::Memcached::Rails)
10
- # def get(key, raw=false)
11
- raw_client.get k.to_s
12
- elsif defined?(::Dalli::Client) and raw_client.is_a?(::Dalli::Client)
13
- # def get(key, options=nil)
14
- raw_client.get k.to_s
15
- elsif defined?(::MemCache) and raw_client.is_a?(::MemCache)
16
- # def get(key, raw = false)
17
- raw_client.get k.to_s
18
- elsif defined?(::ActiveSupport::Cache::Store) and raw_client.is_a?(::ActiveSupport::Cache::Store)
19
- # def read(name, options = nil)
20
- raw_client.read k.to_s
21
- else
22
- raise "Unknown client: #{raw_client.inspect}"
23
- end
24
- end
25
-
26
- def set(k, v)
27
- if defined?(::Memcached) and raw_client.is_a?(::Memcached)
28
- # def set(key, value, ttl=@default_ttl, marshal=true, flags=FLAGS)
29
- raw_client.set k.to_s, v, ttl
30
- elsif defined?(::Memcached::Rails) and raw_client.is_a?(::Memcached::Rails)
31
- # def set(key, value, ttl=@default_ttl, raw=false)
32
- raw_client.set k.to_s, v, ttl
33
- elsif defined?(::Dalli::Client) and raw_client.is_a?(::Dalli::Client)
34
- # def set(key, value, ttl=nil, options=nil)
35
- raw_client.set k.to_s, v, ttl
36
- elsif defined?(::MemCache) and raw_client.is_a?(::MemCache)
37
- # def set(key, value, expiry = 0, raw = false)
38
- raw_client.set k.to_s, v, ttl
39
- elsif defined?(::ActiveSupport::Cache::Store) and raw_client.is_a?(::ActiveSupport::Cache::Store)
40
- # def write(name, value, options = nil)
41
- raw_client.write k.to_s, v, :expires_in => ttl
42
- else
43
- raise "Unknown client: #{raw_client.inspect}"
44
- end
45
- end
@@ -1,45 +0,0 @@
1
- module CacheMethod
2
- class Cache
3
- class Epoch
4
- class << self
5
- def mark_passing(options = {})
6
- e = new options
7
- e.mark_passing
8
- end
9
- def current(options = {})
10
- e = new options
11
- e.current
12
- end
13
- end
14
-
15
- def initialize(options = {})
16
- options.each do |k, v|
17
- instance_variable_set "@#{k}", v
18
- end
19
- end
20
-
21
- attr_reader :obj
22
- attr_reader :method_id
23
-
24
- def method_signature
25
- @method_signature ||= Key.method_signature(obj, method_id)
26
- end
27
-
28
- def obj_hash
29
- @obj_hash ||= obj.hash
30
- end
31
-
32
- def cache_key
33
- [ 'CacheMethod', method_signature, obj_hash ].join ','
34
- end
35
-
36
- def current
37
- Cache.instance.get(cache_key).to_i
38
- end
39
-
40
- def mark_passing
41
- Cache.instance.set cache_key, (current+1), 0
42
- end
43
- end
44
- end
45
- end
@@ -1,56 +0,0 @@
1
- require 'digest/md5'
2
- module CacheMethod
3
- class Cache
4
- class Key
5
- class << self
6
- def digest(*ary)
7
- ::Digest::MD5.hexdigest ary.flatten.map { |i| i.to_s }.join
8
- end
9
- def parse(str)
10
- method_signature, epoch, obj_hash, args_digest = str.split ','
11
- new :method_signature => method_signature, :epoch => epoch, :obj_hash => obj_hash, :args_digest => args_digest
12
- end
13
- def klass_name(obj)
14
- obj.is_a?(::Class) ? obj.to_s : obj.class.to_s
15
- end
16
- def method_delimiter(obj)
17
- obj.is_a?(::Class) ? '.' : '#'
18
- end
19
- def method_signature(obj, method_id)
20
- [ klass_name(obj), method_id ].join method_delimiter(obj)
21
- end
22
- end
23
-
24
- def initialize(options = {})
25
- options.each do |k, v|
26
- instance_variable_set "@#{k}", v
27
- end
28
- end
29
-
30
- attr_reader :obj
31
- attr_reader :method_id
32
- attr_reader :args
33
-
34
- def obj_hash
35
- @obj_hash ||= obj.hash
36
- end
37
-
38
- def args_digest
39
- @args_digest ||= Key.digest(args)
40
- end
41
-
42
- def method_signature
43
- @method_signature ||= Key.method_signature(obj, method_id)
44
- end
45
-
46
- def epoch
47
- @epoch ||= Epoch.current(:obj => obj, :method_id => method_id)
48
- end
49
-
50
- def to_str
51
- [ method_signature, epoch, obj_hash, args_digest ].join ','
52
- end
53
- alias :to_s :to_str
54
- end
55
- end
56
- end
@@ -1,65 +0,0 @@
1
- require 'singleton'
2
- module CacheMethod
3
- # All cache requests go through a clearinghouse, allowing uncaching.
4
- class Cache #:nodoc: all
5
- autoload :Key, 'cache_method/cache/key'
6
- autoload :Epoch, 'cache_method/cache/epoch'
7
-
8
- include ::Singleton
9
-
10
- def flush
11
- bare_client.send %w{ flush flush_all clear flushdb }.detect { |c| bare_client.respond_to? c }
12
- end
13
-
14
- def fetch(obj, method_id, ttl, *args)
15
- k = Key.new :obj => obj, :method_id => method_id, :args => args
16
- if cached_v = get(k.to_s)
17
- return cached_v
18
- end
19
- v = yield
20
- set k.to_s, v, ttl
21
- v
22
- end
23
-
24
- def delete(obj, method_id)
25
- Epoch.mark_passing :obj => obj, :method_id => method_id
26
- end
27
-
28
- def get(k)
29
- if defined?(::Memcached) and bare_client.is_a?(::Memcached)
30
- begin; bare_client.get(k); rescue ::Memcached::NotFound; nil; end
31
- elsif defined?(::Redis) and bare_client.is_a?(::Redis)
32
- if cached_v = bare_client.get(k)
33
- ::Marshal.load cached_v
34
- end
35
- elsif bare_client.respond_to?(:get)
36
- bare_client.get k
37
- elsif bare_client.respond_to?(:read)
38
- bare_client.read k
39
- else
40
- raise "Don't know how to work with #{bare_client.inspect}"
41
- end
42
- end
43
-
44
- def set(k, v, ttl)
45
- ttl ||= ::CacheMethod.config.default_ttl
46
- if defined?(::Redis) and bare_client.is_a?(::Redis)
47
- bare_client.set k, ::Marshal.dump(v)
48
- elsif bare_client.respond_to?(:set)
49
- bare_client.set k, v, ttl
50
- elsif bare_client.respond_to?(:write)
51
- if ttl == 0
52
- bare_client.write k, v # never expire
53
- else
54
- bare_client.write k, v, :expires_in => ttl
55
- end
56
- else
57
- raise "Don't know how to work with #{bare_client.inspect}"
58
- end
59
- end
60
-
61
- def bare_client
62
- ::CacheMethod.config.client
63
- end
64
- end
65
- end
@@ -1,53 +0,0 @@
1
- require 'helper'
2
-
3
- class Blog2
4
- class << self
5
- attr_writer :request_count
6
- def request_count
7
- @request_count ||= 0
8
- end
9
- def get_latest_entries
10
- self.request_count += 1
11
- 'danke schoen'
12
- end
13
- cache_method :get_latest_entries
14
- end
15
- end
16
-
17
- class TestCacheClassMethods < Test::Unit::TestCase
18
- def setup
19
- super
20
- Blog2.request_count = 0
21
- end
22
-
23
- def test_cache_method
24
- assert_equal 0, Blog2.request_count
25
- assert_equal 'danke schoen', Blog2.get_latest_entries
26
- assert_equal 1, Blog2.request_count
27
- assert_equal 'danke schoen', Blog2.get_latest_entries
28
- assert_equal 1, Blog2.request_count
29
- end
30
-
31
- def test_clear_method
32
- assert_equal 0, Blog2.request_count
33
- assert_equal 'danke schoen', Blog2.get_latest_entries
34
- assert_equal 1, Blog2.request_count
35
- Blog2.clear_method_cache :get_latest_entries
36
- assert_equal 'danke schoen', Blog2.get_latest_entries
37
- assert_equal 2, Blog2.request_count
38
- end
39
-
40
- def test_clear_method_doesnt_overstep
41
- assert_equal 0, Blog2.request_count
42
- assert_equal 'danke schoen', Blog2.get_latest_entries
43
- assert_equal 1, Blog2.request_count
44
-
45
- Blog2.clear_method_cache :foobar
46
- assert_equal 'danke schoen', Blog2.get_latest_entries
47
- assert_equal 1, Blog2.request_count
48
-
49
- Blog2.clear_method_cache :get_latest_entries
50
- assert_equal 'danke schoen', Blog2.get_latest_entries
51
- assert_equal 2, Blog2.request_count
52
- end
53
- end