mack-caching 0.8.1 → 0.8.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.
Files changed (27) hide show
  1. data/lib/gems/cachetastic-2.0.0/bin/cachetastic_drb_server +115 -0
  2. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/base.rb +78 -0
  3. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/drb.rb +51 -0
  4. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/file.rb +49 -0
  5. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/file_base.rb +86 -0
  6. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/html_file.rb +68 -0
  7. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/local_memory.rb +68 -0
  8. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/memcache.rb +114 -0
  9. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/store_object.rb +28 -0
  10. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/cacheable.rb +196 -0
  11. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/caches/base.rb +238 -0
  12. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/caches/mack_session_cache.rb +3 -0
  13. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/caches/page_cache.rb +6 -0
  14. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/caches/rails_session_cache.rb +12 -0
  15. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/connection.rb +24 -0
  16. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/errors/unsupported_adapter.rb +7 -0
  17. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/logger.rb +49 -0
  18. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/rails_extensions/active_record_base.rb +24 -0
  19. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/rails_extensions/cgi_session_store.rb +59 -0
  20. data/lib/gems/cachetastic-2.0.0/lib/cachetastic/ruby_extensions/object.rb +8 -0
  21. data/lib/gems/cachetastic-2.0.0/lib/cachetastic.rb +70 -0
  22. data/lib/gems/memcache-client-1.5.0/lib/memcache.rb +805 -0
  23. data/lib/gems/memcache-client-1.5.0/lib/memcache_util.rb +90 -0
  24. data/lib/gems.rb +13 -0
  25. data/lib/mack-caching.rb +2 -1
  26. data/lib/mack-caching_tasks.rb +2 -0
  27. metadata +51 -16
@@ -0,0 +1,196 @@
1
+ module Cachetastic
2
+ # Include this module into an Object to achieve simplistic Object level caching.
3
+ #
4
+ # Example:
5
+ # class Person
6
+ # include Cachetastic::Cacheable
7
+ #
8
+ # attr_accessor :name
9
+ #
10
+ # def cachetastic_key
11
+ # self.name
12
+ # end
13
+ #
14
+ # def always_the_same(x, y)
15
+ # cacher("always_the_same") do
16
+ # x + y
17
+ # end
18
+ # end
19
+ #
20
+ # end
21
+ module Cacheable
22
+
23
+ module ClassAndInstanceMethods
24
+ # Returns the Cachetastic::Caches::Base object associated with the object.
25
+ # If a cache hasn't been defined the one will be created on the fly.
26
+ # The cache for the object is expected to be defined as:
27
+ # Cachetastic::Cacheable::{CLASS_NAME_HERE}Cache
28
+ #
29
+ # Example:
30
+ # class Person
31
+ # include Cachetastic::Cacheable
32
+ # attr_accessor :name
33
+ # def cachetastic_key
34
+ # self.name
35
+ # end
36
+ # end
37
+ #
38
+ # Person.cache_class # => Cachetastic::Cacheable::PersonCache
39
+ def cache_class
40
+ n = self.class.name
41
+ n = self.name if n == "Class"
42
+ # puts "n: #{n}"
43
+ c_name = "Cachetastic::Cacheable::#{n}Cache"
44
+ unless Cachetastic::Cacheable.const_defined?("#{n}Cache")
45
+ # puts "we need to create a cache for: #{c_name}"
46
+ eval %{
47
+ class #{c_name} < Cachetastic::Caches::Base
48
+ end
49
+ }
50
+ end
51
+ c_name.constantize
52
+ end
53
+
54
+ # How much did I want to call this method cache?? It originally was that, but
55
+ # in Rails 2.0 they decided to use that name, so I had to rename this method.
56
+ # This method will attempt to get an object from the cache for a given key.
57
+ # If the object is nil and a block is given the block will be run, and the results
58
+ # of the block will be automatically cached.
59
+ #
60
+ # Example:
61
+ # class Person
62
+ # include Cachetastic::Cacheable
63
+ # attr_accessor :name
64
+ # def cachetastic_key
65
+ # self.name
66
+ # end
67
+ # def always_the_same(x,y)
68
+ # cacher("always_the_same") do
69
+ # x + y
70
+ # end
71
+ # end
72
+ # end
73
+ #
74
+ # Person.new.always_the_same(1,2) # => 3
75
+ # Person.new.always_the_same(2,2) # => 3
76
+ # Person.new.always_the_same(3,3) # => 3
77
+ # Person.cacher("always_the_same") # => 3
78
+ # Person.get_from_cache("always_the_same") # => 3
79
+ # Cachetastic::Cacheable::PersonCache.get("always_the_same") # => 3
80
+ #
81
+ # Person.cacher("say_hi") {"Hi There"} # => "Hi There"
82
+ # Person.get_from_cache("say_hi") # => "Hi There"
83
+ # Cachetastic::Cacheable::PersonCache.get("say_hi") # => "Hi There"
84
+ def cacher(key, expiry = 0)
85
+ cache_class.get(key) do
86
+ if block_given?
87
+ res = yield
88
+ cache_class.set(key, res, expiry)
89
+ end
90
+ end
91
+ end
92
+
93
+ # Expires the entire cache associated with this objects's cache.
94
+ #
95
+ # Example:
96
+ # class Person
97
+ # include Cachetastic::Cacheable
98
+ # attr_accessor :name
99
+ # def cachetastic_key
100
+ # self.name
101
+ # end
102
+ # end
103
+ #
104
+ # Person.set_into_cache(1, "one")
105
+ # Person.get_from_cache(1) # => "one"
106
+ # Person.expire_all
107
+ # Person.get_from_cache(1) # => nil
108
+ # Person.set_into_cache(1, "one")
109
+ # Person.get_from_cache(1) # => "one"
110
+ # Cachetastic::Cacheable::PersonCache.expire_all
111
+ # Person.get_from_cache(1) # => nil
112
+ def expire_all
113
+ cache_class.expire_all
114
+ end
115
+ end
116
+
117
+ # --------------------------
118
+ # Instance only methods:
119
+
120
+ # Unless the object's cachetastic_key method returns nil this method will store
121
+ # the object in the cache using the object's cachetastic_key as the key.
122
+ # You *MUST* create an instance level method called cachetastic_key and
123
+ # have it return a valid key! If you return nil from the cachetastic_key method or you will not be
124
+ # able to use the cache_self and uncache_self methods.
125
+ #
126
+ # Example:
127
+ # class Person
128
+ # include Cachetastic::Cacheable
129
+ # attr_accessor :name
130
+ # def cachetastic_key
131
+ # self.name
132
+ # end
133
+ # end
134
+ #
135
+ # Person.get_from_cache("Mark Bates") # => nil
136
+ # p = Person.new
137
+ # p.name = "Mark Bates"
138
+ # p.cache_self
139
+ # Person.get_from_cache("Mark Bates") # => "Mark Bates"
140
+ def cache_self
141
+ cache_class.set(self.cachetastic_key, self) unless self.cachetastic_key.nil?
142
+ end
143
+
144
+ # Unless the object's cachetastic_key method returns nil this method will delete
145
+ # the object in the cache using the object's cachetastic_key as the key.
146
+ # You *MUST* create an instance level method called cachetastic_key and
147
+ # have it return a valid key! If you return nil from the cachetastic_key method or you will not be
148
+ # able to use the cache_self and uncache_self methods.
149
+ #
150
+ # Example:
151
+ # class Person
152
+ # include Cachetastic::Cacheable
153
+ # attr_accessor :name
154
+ # def cachetastic_key
155
+ # self.name
156
+ # end
157
+ # end
158
+ #
159
+ # Person.get_from_cache("Mark Bates") # => nil
160
+ # p = Person.new
161
+ # p.name = "Mark Bates"
162
+ # p.cache_self
163
+ # Person.get_from_cache("Mark Bates") # => "Mark Bates"
164
+ # p.uncache_self
165
+ # Person.get_from_cache("Mark Bates") # => nil
166
+ def uncache_self
167
+ cache_class.delete(self.cachetastic_key) unless self.cachetastic_key.nil?
168
+ end
169
+
170
+ # --------------------------
171
+
172
+ def self.included(klass) # :nodoc:
173
+ klass.send(:include, ClassAndInstanceMethods)
174
+ klass.extend(ClassOnlyMethods)
175
+ klass.extend(ClassAndInstanceMethods)
176
+ end
177
+
178
+ module ClassOnlyMethods
179
+ # Returns an object from the cache for a given key.
180
+ def get_from_cache(key, &block)
181
+ cache_class.get(key, &block)
182
+ end
183
+
184
+ # Deletes an object from the cache for a given key.
185
+ def delete_from_cache(key)
186
+ cache_class.delete(key)
187
+ end
188
+
189
+ # Sets an object into the cache for a given key.
190
+ def set_into_cache(key, value, expiry = 0)
191
+ cache_class.set(key, value, expiry)
192
+ end
193
+ end # ClassMethods
194
+
195
+ end # Cacheable
196
+ end # Cachetastic
@@ -0,0 +1,238 @@
1
+ require 'singleton'
2
+ # When creating a new 'Cache' this class should be extended.
3
+ # Once extended you'll only need to override just the methods
4
+ # that are different for your cache.
5
+ # class MyAwesomeCache < Cachetastic::Caches::Base
6
+ # end
7
+ # MyAwesomeCache.set(1, "One")
8
+ # MyAwesomeCache.get(1) # => "One"
9
+ # MyAwesomeCache.update(1, "One!!")
10
+ # MyAwesomeCache.get(1) # => "One!!"
11
+ # MyAwesomeCache.delete(1)
12
+ # MyAwesomeCache.get(1) # => nil
13
+ #
14
+ # class MyAwesomeCache < Cachetastic::Caches::Base
15
+ # class << self
16
+ # def get(key)
17
+ # super(key) do
18
+ # set(key, key * 10)
19
+ # end
20
+ # end
21
+ # end
22
+ # end
23
+ # MyAwesomeCache.set(1, "One")
24
+ # MyAwesomeCache.get(1) # => "One"
25
+ # MyAwesomeCache.delete(1)
26
+ # MyAwesomeCache.get(1) # => 10
27
+ class Cachetastic::Caches::Base
28
+
29
+ # Used to store a list of all the caches registered with the system.
30
+ # In order for a cache to be registered it must extend Cachetastic::Caches::Base.
31
+ class RegisteredCaches
32
+ include Singleton
33
+
34
+ # list of all caches registered with the system.
35
+ attr_reader :list
36
+
37
+ def initialize
38
+ @list = []
39
+ end
40
+
41
+ end
42
+
43
+ # everything is done at the class level. there won't be any 'instances of it'
44
+ # using class << self means we don't have to prefix each method with 'self.'
45
+ class << self
46
+
47
+ # Returns a list of all registered caches in the system.
48
+ def all_registered_caches
49
+ RegisteredCaches.instance.list
50
+ end
51
+
52
+ # Returns an object from the cache for a given key.
53
+ # If the object comes back as nil and a block is given
54
+ # that block will be run and the results of the block
55
+ # will be run. This can be used to JIT caches, just make
56
+ # sure in the block to call the set method because the
57
+ # results of the block are not automatically cached.
58
+ def get(key, &block)
59
+ res = nil
60
+ do_with_logging(:get, key) do
61
+ retryable(:on => ArgumentError) do
62
+ begin
63
+ res = adapter.get(key.to_s)
64
+ if res.nil?
65
+ res = yield key if block_given?
66
+ else
67
+ res = unmarshall(res)
68
+ end
69
+ res
70
+ rescue ArgumentError => e
71
+ m = e.message.match(/class\/module .*/)
72
+ if m
73
+ m = m.to_s
74
+ m.gsub!("class/module", '')
75
+ m.gsub!("(ArgumentError)", '')
76
+ require m.strip.underscore
77
+ raise e
78
+ end
79
+ rescue Exception => e
80
+ raise e
81
+ end
82
+ end
83
+ end
84
+ res
85
+ end
86
+
87
+ # Set a particular object info the cache for the given key.
88
+ # An optional third parameter sets the expiry time for the object in the cache.
89
+ # The default for this expiry is set as either 0, meaning it never expires, or
90
+ # if there's a default_expiry time set in the config file, that file will be
91
+ # used.
92
+ # If there is an expiry_swing set in the config file it will be +/- to the
93
+ # expiry time. See also: calculate_expiry_time
94
+ def set(key, value, expiry = adapter.configuration.retrieve(:default_expiry, 0))
95
+ do_with_logging(:set, key) do
96
+ expiry = calculate_expiry_time(expiry)
97
+ adapter.set(key.to_s, marshall(value), expiry.to_i)
98
+ logger.info('', '', :expiry, cache_name, key, expiry.to_i)
99
+ value
100
+ end
101
+ end
102
+
103
+ alias_method :put, :set
104
+
105
+ # Deletes an object from the cache. The optional delay parameter
106
+ # sets an offset, in seconds, for when the object should get deleted.
107
+ # The default of 0 means the object gets deleted right away.
108
+ def delete(key, delay = 0)
109
+ do_with_logging(:delete, key) do
110
+ adapter.delete(key.to_s, delay)
111
+ end
112
+ end
113
+
114
+ # Expires all objects for this cache.
115
+ def expire_all
116
+ adapter.expire_all
117
+ logger.info('', '', :expired, cache_name)
118
+ end
119
+
120
+ # Raises a MethodNotImplemented exception. This method should be overridden
121
+ # in the child class to enable a populating the cache with all things that
122
+ # should be in there.
123
+ needs_method :populate_all
124
+
125
+ # A convenience method that returns statistics for the underlying Cachetastic::Adapters::Base for the cache.
126
+ def stats
127
+ adapter.stats
128
+ end
129
+
130
+ # Returns a 'methodize' version of the cache's class name. This gets used in logging,
131
+ # namespacing, and as the key in the Cachetastic::Connection class.
132
+ # MyAwesomeCache.cache # => "my_awesome_cache"
133
+ # Cachetastic::Caches::Base # => "cachetastic_caches_base"
134
+ def cache_name
135
+ self.name.methodize
136
+ end
137
+
138
+ # Returns the underlying Cachetastic::Adapters::Base for this cache.
139
+ def adapter
140
+ a = cache_conn_instance.get(cache_name)
141
+ if adapter_supported?(a.class)
142
+ return a
143
+ else
144
+ raise Cachetastic::Errors::UnsupportedAdapter.new(cache_name, a.class)
145
+ end
146
+ end
147
+
148
+ # Returns the Cachetastic::Logger for the underlying Cachetastic::Adapters::Base.
149
+ def logger
150
+ adapter.logger
151
+ end
152
+
153
+ # Returns an array of unsupported adapters for this cache. Defaults to an empty
154
+ # array which will let any adapter be used by the cache. Override in your specific
155
+ # cache to prevent certain adapters.
156
+ def unsupported_adapters
157
+ []
158
+ end
159
+
160
+ # Returns true/false on whether the adapter you want to use is supported for the cache.
161
+ def adapter_supported?(a = cache_conn_instance.get(cache_name).class)
162
+ return !unsupported_adapters.include?(a)
163
+ end
164
+
165
+ def marshall(value)
166
+ return value if value.nil?
167
+ return case adapter.configuration.retrieve(:marshall_method, :none).to_sym
168
+ when :yaml
169
+ YAML.dump(value)
170
+ when :ruby
171
+ Marshal.dump(value)
172
+ else
173
+ value
174
+ end
175
+ end
176
+
177
+ def unmarshall(value)
178
+ return value if value.nil?
179
+ return case adapter.configuration.retrieve(:marshall_method, :none).to_sym
180
+ when :yaml
181
+ YAML.load(value)
182
+ when :ruby
183
+ Marshal.load(value)
184
+ else
185
+ value
186
+ end
187
+ end
188
+
189
+ private
190
+ # If the expiry time is set to 60 minutes and the expiry_swing time is set to
191
+ # 15 minutes, this method will return a number between 45 minutes and 75 minutes.
192
+ def calculate_expiry_time(expiry) # :doc:
193
+ exp_swing = adapter.configuration.retrieve(:expiry_swing, 0)
194
+ if exp_swing && exp_swing != 0
195
+ swing = rand(exp_swing.to_i)
196
+ case rand(2)
197
+ when 0
198
+ expiry = (expiry.to_i + swing)
199
+ when 1
200
+ expiry = (expiry.to_i - swing)
201
+ end
202
+ end
203
+ expiry
204
+ end
205
+
206
+ def inherited(child)
207
+ # puts "child: #{child.inspect}"
208
+ all_registered_caches << child.to_s
209
+ # puts "all_registered_caches: #{all_registered_caches.inspect}"
210
+ end
211
+
212
+ def cache_conn_instance
213
+ Cachetastic::Connection.instance
214
+ end
215
+
216
+ def do_with_logging(action, key)
217
+ start_time = Time.now
218
+ logger.info(:starting, action, cache_name, key)
219
+ res = yield if block_given?
220
+ end_time = Time.now
221
+ str = ""
222
+ unless res.nil?
223
+ str = "[#{res.class.name}]"
224
+ str << "\t[Size = #{res.size}]" if res.respond_to? :size
225
+ str << "\t" << res.inspect if adapter.debug?
226
+ end
227
+ logger.info(:finished, action, cache_name, key, (end_time - start_time), str)
228
+ res
229
+ end
230
+
231
+ # make sure people can't instaniate this object!
232
+ def new(*args)
233
+ raise NoMethodError.new("You can not instaniate this class!")
234
+ end
235
+
236
+ end
237
+
238
+ end
@@ -0,0 +1,3 @@
1
+ # Used for storing Mack sessions.
2
+ class Cachetastic::Caches::MackSessionCache < Cachetastic::Caches::Base
3
+ end
@@ -0,0 +1,6 @@
1
+ # Used by the Mongrel Page Cache Handler gem for page caching.
2
+ # Future functionality may be added to this class to allow for
3
+ # things such as deleting a certain page/set of pages based on
4
+ # regex, etc...
5
+ class Cachetastic::Caches::PageCache < Cachetastic::Caches::Base
6
+ end
@@ -0,0 +1,12 @@
1
+ # Used for storing Rails sessions.
2
+ class Cachetastic::Caches::RailsSessionCache < Cachetastic::Caches::Base
3
+
4
+ class << self
5
+
6
+ def unsupported_adapters
7
+ [Cachetastic::Adapters::File]
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,24 @@
1
+ # This class caches adapter objects for each cache in the system.
2
+ class Cachetastic::Connection
3
+ include Singleton
4
+
5
+ attr_accessor :connections
6
+
7
+ def initialize
8
+ self.connections = {}
9
+ end
10
+
11
+ # Takes the name of the cache, that's been methodized, and returns back the adapter object associated with the cache.
12
+ # If the adapter object doesn't exist or if the adapter is no longer valid (adapter.valid?) a new one is
13
+ # created and returned.
14
+ def get(name)
15
+ name = name.to_sym
16
+ conn = self.connections[name]
17
+ return conn if conn && conn.valid?
18
+ adapter = Cachetastic::Adapters::Base.configuration(name).adapter.to_s.camelcase
19
+ conn = "Cachetastic::Adapters::#{adapter}".constantize.new(name)
20
+ self.connections[name.to_sym] = conn
21
+ return conn
22
+ end
23
+
24
+ end
@@ -0,0 +1,7 @@
1
+ class Cachetastic::Errors::UnsupportedAdapter < Exception
2
+
3
+ def initialize(cache_name, adapter)
4
+ super("#{cache_name} does not support the use of the #{adapter} adapter!")
5
+ end
6
+
7
+ end
@@ -0,0 +1,49 @@
1
+ # This class handles logging for the caches and their adapters.
2
+ class Cachetastic::Logger
3
+
4
+ # attr_accessor :options
5
+ # attr_accessor :cache_name
6
+ attr_accessor :loggers
7
+
8
+ def initialize(loggers)
9
+ @loggers = [loggers].flatten
10
+ # self.options = options
11
+ # self.cache_name = cache_name
12
+ # self.options.each_pair do |n, opts|
13
+ # opts["level"] = (opts["level"] ||= "info").to_sym
14
+ # end
15
+ end
16
+
17
+ LOG_LEVELS = [:fatal, :error, :warn, :info, :debug]
18
+
19
+ LOG_LEVELS.each do |level|
20
+ define_method(level) do |*args|
21
+ lm = "[CACHE] [#{level.to_s.upcase}]\t#{Time.now.strftime("%m/%d/%y %H:%M:%S")}"
22
+ exs = []
23
+ args.each do |arg|
24
+ if arg.is_a?(Exception)
25
+ exs << arg
26
+ continue
27
+ end
28
+ lm << "\t" << arg.to_s
29
+ end
30
+ exs.each do |ex|
31
+ lm << "\n#{ex.message}\n" << ex.backtrace.join("\n")
32
+ end
33
+ self.loggers.each do |log|
34
+ log.send(level, lm)
35
+ end
36
+ # self.options.each_pair do |n, opts|
37
+ # if LOG_LEVELS.index(opts["level"]) >= LOG_LEVELS.index(level)
38
+ # case opts["type"]
39
+ # when "file"
40
+ # File.open(opts["file"], "a") {|f| f.puts(lm)}
41
+ # when "console"
42
+ # puts lm
43
+ # end
44
+ # end
45
+ # end
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,24 @@
1
+ class ActiveRecord::Base
2
+
3
+ include Cachetastic::Cacheable
4
+
5
+ def cachetastic_key
6
+ self.id
7
+ end
8
+
9
+ # Returns an object from the cache for a given key.
10
+ # If the object returned is nil and the self_populate parameter is true
11
+ # then the key will be used to try and find the object in the database,
12
+ # set the object into the cache, and then return the object.
13
+ def self.get_from_cache(key, self_populate = false)
14
+ res = cache_class.get(key)
15
+ if res.nil? && self_populate
16
+ res = self.name.constantize.find(key)
17
+ unless res.nil?
18
+ res.cache_self
19
+ end
20
+ end
21
+ res
22
+ end
23
+
24
+ end
@@ -0,0 +1,59 @@
1
+ require 'cgi'
2
+ require 'cgi/session'
3
+
4
+ class CGI #:nodoc:#
5
+ class Session #:nodoc:#
6
+ # Allows Rails to use Cachetastic for it's session store.
7
+ # The setting below needs to happen AFTER the gem has been required, obviously!
8
+ # In Rails 1.2.6 this is AFTER the initializer block.
9
+ # ActionController::Base.session_store = :cachetastic_store
10
+ class CachetasticStore
11
+
12
+
13
+ def check_id(id) #:nodoc:#
14
+ /[^0-9a-zA-Z]+/ =~ id.to_s ? false : true
15
+ end
16
+
17
+ def initialize(session, options = {}) #:nodoc:#
18
+ id = session.session_id
19
+ unless check_id(id)
20
+ raise ArgumentError, "session_id '%s' is invalid" % id
21
+ end
22
+
23
+ @session_key = id
24
+
25
+ @session_data = {}
26
+ end
27
+
28
+ # Restore session state from the session's memcache entry.
29
+ #
30
+ # Returns the session state as a hash.
31
+ def restore #:nodoc:#
32
+ @session_data = Cachetastic::Caches::RailsSessionCache.get(@session_key) do
33
+ {}
34
+ end
35
+ end
36
+
37
+ # Save session state to the session's memcache entry.
38
+ def update #:nodoc:#
39
+ Cachetastic::Caches::RailsSessionCache.set(@session_key, @session_data)
40
+ end
41
+
42
+ # Update and close the session's memcache entry.
43
+ def close #:nodoc:#
44
+ update
45
+ end
46
+
47
+ # Delete the session's memcache entry.
48
+ def delete #:nodoc:#
49
+ Cachetastic::Caches::RailsSessionCache.delete(@session_key)
50
+ @session_data = {}
51
+ end
52
+
53
+ def data #:nodoc:#
54
+ @session_data
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,8 @@
1
+ class Object
2
+
3
+ # Override this method in your object if you use the Cachetastic::Cacheable module.
4
+ def cachetastic_key
5
+ raise NoMethodError.new('cachetastic_key')
6
+ end
7
+
8
+ end