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.
- data/lib/gems/cachetastic-2.0.0/bin/cachetastic_drb_server +115 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/base.rb +78 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/drb.rb +51 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/file.rb +49 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/file_base.rb +86 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/html_file.rb +68 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/local_memory.rb +68 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/memcache.rb +114 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/adapters/store_object.rb +28 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/cacheable.rb +196 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/caches/base.rb +238 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/caches/mack_session_cache.rb +3 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/caches/page_cache.rb +6 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/caches/rails_session_cache.rb +12 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/connection.rb +24 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/errors/unsupported_adapter.rb +7 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/logger.rb +49 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/rails_extensions/active_record_base.rb +24 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/rails_extensions/cgi_session_store.rb +59 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic/ruby_extensions/object.rb +8 -0
- data/lib/gems/cachetastic-2.0.0/lib/cachetastic.rb +70 -0
- data/lib/gems/memcache-client-1.5.0/lib/memcache.rb +805 -0
- data/lib/gems/memcache-client-1.5.0/lib/memcache_util.rb +90 -0
- data/lib/gems.rb +13 -0
- data/lib/mack-caching.rb +2 -1
- data/lib/mack-caching_tasks.rb +2 -0
- 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,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,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,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
|