mack-caching 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|