cachetastic 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/init.rb +1 -0
- data/lib/caches/cachetastic_caches_base.rb +108 -0
- data/lib/caches/cachetastic_caches_page_cache.rb +3 -0
- data/lib/caches/cachetastic_caches_rails_session_cache.rb +3 -0
- data/lib/cachetastic.rb +32 -0
- data/lib/cachetastic_connection.rb +20 -0
- data/lib/cachetastic_logger.rb +51 -0
- data/lib/helpers/cachetastic_helpers_active_record.rb +35 -0
- data/lib/rails_extensions/cachetastic_active_record_base.rb +37 -0
- data/lib/rails_extensions/cgi_session_cachetastic_store.rb +54 -0
- data/lib/stores/cachetastic_stores_base.rb +70 -0
- data/lib/stores/cachetastic_stores_local_memory.rb +71 -0
- data/lib/stores/cachetastic_stores_memcache.rb +67 -0
- data/lib/tasks/rubyforge_config.yml +5 -0
- metadata +61 -0
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
#require 'cachetastic'
|
@@ -0,0 +1,108 @@
|
|
1
|
+
class Cachetastic::Caches::Base
|
2
|
+
|
3
|
+
# everything is done at the class level. there won't be any 'instances of it'
|
4
|
+
# using class << self means we don't have to prefix each method with 'self.'
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def get(key)
|
8
|
+
res = nil
|
9
|
+
do_with_logging(:get, key) do
|
10
|
+
res = store.get(key.to_s)
|
11
|
+
if res.nil?
|
12
|
+
res = yield if block_given?
|
13
|
+
else
|
14
|
+
res = unmarshall(res)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
res
|
18
|
+
end
|
19
|
+
|
20
|
+
def set(key, value, expiry = (store.all_options["default_expiry"] || 0))
|
21
|
+
do_with_logging(:set, key) do
|
22
|
+
exp_swing = store.all_options["expiry_swing"]
|
23
|
+
if exp_swing
|
24
|
+
swing = rand(exp_swing.to_i)
|
25
|
+
case rand(2)
|
26
|
+
when 0
|
27
|
+
expiry = (expiry.to_i + swing)
|
28
|
+
when 1
|
29
|
+
expiry = (expiry.to_i - swing)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
store.set(key.to_s, marshall(value), expiry.to_i)
|
33
|
+
logger.info('', '', :expiry, cache_name, key, expiry.to_i)
|
34
|
+
value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
alias_method :put, :set
|
39
|
+
|
40
|
+
def delete(key, delay = 0)
|
41
|
+
do_with_logging(:delete, key) do
|
42
|
+
store.delete(key.to_s, delay)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def expire_all
|
47
|
+
store.expire_all
|
48
|
+
logger.info('', '', :expired, cache_name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def cache_name
|
52
|
+
self.name.methodize
|
53
|
+
end
|
54
|
+
|
55
|
+
def store
|
56
|
+
cache_conn_instance.get(cache_name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def logger
|
60
|
+
store.logger
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
def marshall(value)
|
65
|
+
return case store.all_options["marshall_method"]
|
66
|
+
when "yaml"
|
67
|
+
YAML.dump(value)
|
68
|
+
else
|
69
|
+
value
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def unmarshall(value)
|
74
|
+
return case store.all_options["marshall_method"]
|
75
|
+
when "yaml"
|
76
|
+
YAML.load(value)
|
77
|
+
else
|
78
|
+
value
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def cache_conn_instance
|
83
|
+
Cachetastic::Connection.instance
|
84
|
+
end
|
85
|
+
|
86
|
+
def do_with_logging(action, key)
|
87
|
+
start_time = Time.now
|
88
|
+
logger.info(:starting, action, cache_name, key)
|
89
|
+
res = yield if block_given?
|
90
|
+
end_time = Time.now
|
91
|
+
str = ""
|
92
|
+
unless res.nil?
|
93
|
+
str = "[#{res.class.name}]"
|
94
|
+
str << "\t[Size = #{res.size}]" if res.respond_to? :size
|
95
|
+
str << "\t" << res.inspect if store.debug?
|
96
|
+
end
|
97
|
+
logger.info(:finished, action, cache_name, key, (end_time - start_time), str)
|
98
|
+
res
|
99
|
+
end
|
100
|
+
|
101
|
+
# make sure people can't instaniate this object!
|
102
|
+
def new(*args)
|
103
|
+
raise MethodNotImplemented.new("You can not instaniate this class!")
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
data/lib/cachetastic.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'memcache'
|
3
|
+
require 'singleton'
|
4
|
+
require 'logger'
|
5
|
+
require 'yaml'
|
6
|
+
require 'zlib'
|
7
|
+
require 'pp'
|
8
|
+
|
9
|
+
module Cachetastic
|
10
|
+
module Caches
|
11
|
+
module ActiveRecord
|
12
|
+
end
|
13
|
+
end
|
14
|
+
module Stores
|
15
|
+
end
|
16
|
+
module Helpers
|
17
|
+
module ActiveRecord
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'cachetastic_connection'
|
23
|
+
require 'cachetastic_logger'
|
24
|
+
require 'caches/cachetastic_caches_base'
|
25
|
+
require 'caches/cachetastic_caches_page_cache'
|
26
|
+
require 'caches/cachetastic_caches_rails_session_cache'
|
27
|
+
require 'stores/cachetastic_stores_base'
|
28
|
+
require 'stores/cachetastic_stores_memcache'
|
29
|
+
require 'stores/cachetastic_stores_local_memory'
|
30
|
+
require 'helpers/cachetastic_helpers_active_record'
|
31
|
+
require 'rails_extensions/cachetastic_active_record_base'
|
32
|
+
require 'rails_extensions/cgi_session_cachetastic_store'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Cachetastic::Connection
|
2
|
+
include Singleton
|
3
|
+
|
4
|
+
attr_accessor :connections
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
self.connections = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def get(name)
|
11
|
+
name = name.to_sym
|
12
|
+
conn = self.connections[name]
|
13
|
+
return conn if conn && conn.valid?
|
14
|
+
store = Cachetastic::Stores::Base.get_options(name)["store"].camelcase
|
15
|
+
conn = "Cachetastic::Stores::#{store}".constantize.new(name)
|
16
|
+
self.connections[name] = conn
|
17
|
+
return conn
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class Cachetastic::Logger
|
2
|
+
|
3
|
+
attr_accessor :options
|
4
|
+
attr_accessor :cache_name
|
5
|
+
|
6
|
+
def initialize(options, cache_name)
|
7
|
+
self.options = options
|
8
|
+
# puts "self.options = #{self.options.inspect}"
|
9
|
+
self.cache_name = cache_name
|
10
|
+
self.options.each_pair do |n, opts|
|
11
|
+
# puts "opts: #{opts.inspect}"
|
12
|
+
# puts "asdfasfsadfaf opts[\"level\"] = #{opts["level"]}"
|
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
|
+
# puts "logging for: #{level}"
|
22
|
+
lm = "[CACHE] [#{level.to_s.upcase}]\t#{Time.now.strftime("%m/%d/%y %H:%m:%S")}"
|
23
|
+
exs = []
|
24
|
+
args.each do |arg|
|
25
|
+
if arg.is_a?(Exception)
|
26
|
+
exs << arg
|
27
|
+
continue
|
28
|
+
end
|
29
|
+
lm << "\t" << arg.to_s
|
30
|
+
end
|
31
|
+
exs.each do |ex|
|
32
|
+
lm << "\n#{ex.message}\n" << ex.backtrace.join("\n")
|
33
|
+
end
|
34
|
+
self.options.each_pair do |n, opts|
|
35
|
+
# puts "opts[\"level\"]: #{opts["level"]}"
|
36
|
+
# # if level == opts["level"]
|
37
|
+
# puts "LOG_LEVELS.index(opts[\"level\"]): #{LOG_LEVELS.index(opts["level"])} (#{opts["level"]})"
|
38
|
+
# puts "LOG_LEVELS.index(level): #{LOG_LEVELS.index(level)} (#{level})"
|
39
|
+
if LOG_LEVELS.index(opts["level"]) >= LOG_LEVELS.index(level)
|
40
|
+
case opts["type"]
|
41
|
+
when "file"
|
42
|
+
File.open(opts["file"], "a") {|f| f.puts(lm)}
|
43
|
+
when "console"
|
44
|
+
puts lm
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Cachetastic
|
2
|
+
module Helpers
|
3
|
+
module ActiveRecord
|
4
|
+
|
5
|
+
def cache_class
|
6
|
+
n = self.class.name
|
7
|
+
n = self.name if n == "Class"
|
8
|
+
# puts "n: #{n}"
|
9
|
+
c_name = "Cachetastic::Caches::ActiveRecord::#{n}Cache"
|
10
|
+
unless Cachetastic::Caches::ActiveRecord.const_defined?("#{n}Cache")
|
11
|
+
# puts "we need to create a cache for: #{c_name}"
|
12
|
+
eval %{
|
13
|
+
class #{c_name} < Cachetastic::Caches::Base
|
14
|
+
end
|
15
|
+
}
|
16
|
+
end
|
17
|
+
c_name.constantize
|
18
|
+
end
|
19
|
+
|
20
|
+
def cache(key, expiry = 0)
|
21
|
+
cache_class.get(key) do
|
22
|
+
if block_given?
|
23
|
+
res = yield
|
24
|
+
cache_class.set(key, res, expiry)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def expire_all
|
30
|
+
cache_class.expire_all
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class ActiveRecord::Base
|
2
|
+
|
3
|
+
include Cachetastic::Helpers::ActiveRecord # include helpers at instance level
|
4
|
+
|
5
|
+
class << self
|
6
|
+
include Cachetastic::Helpers::ActiveRecord # include helpers at class level
|
7
|
+
|
8
|
+
def get_from_cache(key, self_populate = false)
|
9
|
+
res = cache_class.get(key)
|
10
|
+
if res.nil? && self_populate
|
11
|
+
res = self.name.constantize.find(key)
|
12
|
+
unless res.nil?
|
13
|
+
res.cache_self
|
14
|
+
end
|
15
|
+
end
|
16
|
+
res
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete_from_cache(key)
|
20
|
+
cache_class.delete(key)
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_into_cache(key, value, expiry = 0)
|
24
|
+
cache_class.set(key, value, expiry)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def cache_self
|
30
|
+
cache_class.set(self.id, self) unless self.new_record?
|
31
|
+
end
|
32
|
+
|
33
|
+
def uncache_self
|
34
|
+
cache_class.delete(self.id) unless self.new_record?
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'cgi/session'
|
3
|
+
|
4
|
+
class CGI #:nodoc:all
|
5
|
+
class Session
|
6
|
+
class CachetasticStore
|
7
|
+
|
8
|
+
def check_id(id) #:nodoc:#
|
9
|
+
/[^0-9a-zA-Z]+/ =~ id.to_s ? false : true
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(session, options = {})
|
13
|
+
id = session.session_id
|
14
|
+
unless check_id(id)
|
15
|
+
raise ArgumentError, "session_id '%s' is invalid" % id
|
16
|
+
end
|
17
|
+
|
18
|
+
@session_key = id
|
19
|
+
|
20
|
+
@session_data = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Restore session state from the session's memcache entry.
|
24
|
+
#
|
25
|
+
# Returns the session state as a hash.
|
26
|
+
def restore
|
27
|
+
@session_data = Cachetastic::Caches::RailsSessionCache.get(@session_key) do
|
28
|
+
{}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Save session state to the session's memcache entry.
|
33
|
+
def update
|
34
|
+
Cachetastic::Caches::RailsSessionCache.set(@session_key, @session_data)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Update and close the session's memcache entry.
|
38
|
+
def close
|
39
|
+
update
|
40
|
+
end
|
41
|
+
|
42
|
+
# Delete the session's memcache entry.
|
43
|
+
def delete
|
44
|
+
Cachetastic::Caches::RailsSessionCache.delete(@session_key)
|
45
|
+
@session_data = {}
|
46
|
+
end
|
47
|
+
|
48
|
+
def data
|
49
|
+
@session_data
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class Cachetastic::Stores::Base
|
2
|
+
|
3
|
+
attr_reader :all_options
|
4
|
+
attr_reader :store_options
|
5
|
+
attr_reader :servers
|
6
|
+
attr_reader :name
|
7
|
+
attr_reader :logging
|
8
|
+
attr_reader :logger
|
9
|
+
|
10
|
+
def initialize(name)
|
11
|
+
@name = name
|
12
|
+
configure
|
13
|
+
setup
|
14
|
+
if self.debug?
|
15
|
+
self.logger.debug(self.name, :self, self.inspect)
|
16
|
+
self.logger.debug(self.name, :options, self.all_options.inspect)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid?
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
[:setup, :set, :get, :delete, :expire_all].each do |meth|
|
25
|
+
define_method(meth) do |*args|
|
26
|
+
raise MethodNotImplemented.new(meth)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def debug?
|
31
|
+
ivar_cache(:debug) do
|
32
|
+
(self.all_options["debug"] == true || false)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def configure
|
37
|
+
@all_options = Cachetastic::Stores::Base.get_options(self.name)
|
38
|
+
@store_options = (self.all_options["store_options"] || {})
|
39
|
+
@servers = self.all_options["servers"]
|
40
|
+
@logging = (self.all_options["logging"] || {})
|
41
|
+
@logger = Cachetastic::Logger.new(self.logging, self.name)
|
42
|
+
end
|
43
|
+
|
44
|
+
# def log(mess, ex = nil)
|
45
|
+
# self.logging.each_pair do |n, opts|
|
46
|
+
#
|
47
|
+
# lm = "[CACHE]\t#{Time.now}:\t#{mess}"
|
48
|
+
# lm << "\n#{ex.message}\n" << ex.backtrace.join("\n") if ex
|
49
|
+
#
|
50
|
+
# case opts["type"]
|
51
|
+
# when "file"
|
52
|
+
# File.open(opts["file"], "a") {|f| f.puts(lm)}
|
53
|
+
# when "console"
|
54
|
+
# puts lm
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
class << self
|
62
|
+
def get_options(name)
|
63
|
+
options = app_config.cachetastic_default_options
|
64
|
+
options.merge!(app_config.send(name.methodize + "_options") || {})
|
65
|
+
options = {"store" => "local_memory"}.merge(options)
|
66
|
+
options
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class Cachetastic::Stores::LocalMemory < Cachetastic::Stores::Base
|
2
|
+
|
3
|
+
attr_accessor :local_store
|
4
|
+
|
5
|
+
def valid?
|
6
|
+
true
|
7
|
+
end
|
8
|
+
|
9
|
+
def setup
|
10
|
+
self.local_store = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def expire_all
|
14
|
+
self.local_store = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def get(key)
|
18
|
+
so = self.local_store[key.to_s]
|
19
|
+
if so
|
20
|
+
if Time.now >= so.expires_at
|
21
|
+
self.delete(key)
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
return so.value
|
25
|
+
end
|
26
|
+
return nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def set(key, value, expiry = 0)
|
30
|
+
self.local_store[key.to_s] = StoreObject.new(key.to_s, value, expiry)
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete(key, delay = 0)
|
34
|
+
if delay <= 0
|
35
|
+
self.local_store.delete(key.to_s)
|
36
|
+
else
|
37
|
+
so = self.get(key)
|
38
|
+
if so
|
39
|
+
self.set(so.key, so.value, delay)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
class StoreObject
|
46
|
+
attr_accessor :key
|
47
|
+
attr_accessor :value
|
48
|
+
attr_accessor :expires_at
|
49
|
+
|
50
|
+
def initialize(key, value, expiry)
|
51
|
+
# puts "expiry: #{expiry}"
|
52
|
+
self.key = key
|
53
|
+
self.value = value
|
54
|
+
begin
|
55
|
+
self.expires_at = (Time.now + (expiry == 0 ? (31536000) : expiry)) # 31536000 = one year
|
56
|
+
rescue RangeError => e
|
57
|
+
self.expires_at = Time.at(expiry)
|
58
|
+
end
|
59
|
+
# puts "now: #{Time.now}"
|
60
|
+
# puts "expiry: #{expiry}"
|
61
|
+
# puts "expires_at: #{self.expires_at}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def size
|
65
|
+
return self.value.size if self.value.respond_to?(:size)
|
66
|
+
-1
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class Cachetastic::Stores::Memcache < Cachetastic::Stores::Base
|
2
|
+
|
3
|
+
def setup
|
4
|
+
self.conn = MemCache.new(self.servers, self.store_options.merge({:namespace => self.namespace}))
|
5
|
+
self.version = self.get_version(self.name)
|
6
|
+
end
|
7
|
+
|
8
|
+
def set(key, value, expiry = 0)
|
9
|
+
self.conn.set(key, value, expiry)
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete(key, delay = 0)
|
13
|
+
self.conn.delete(key, delay)
|
14
|
+
end
|
15
|
+
|
16
|
+
def get(key)
|
17
|
+
self.conn.get(key)
|
18
|
+
end
|
19
|
+
|
20
|
+
def expire_all
|
21
|
+
self.increment_version(self.name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def inspect
|
25
|
+
self.conn.inspect + " <version: #{self.version}> #{self.conn.stats.inspect}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def namespace
|
29
|
+
v = self.get_version(self.name)
|
30
|
+
return "#{name}.#{v}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def valid?
|
34
|
+
begin
|
35
|
+
return (self.active? && self.version == self.get_version(self.name))
|
36
|
+
rescue Exception => e
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
attr_accessor :conn
|
43
|
+
attr_accessor :version
|
44
|
+
|
45
|
+
def ns_versions
|
46
|
+
ivar_cache do
|
47
|
+
ns_conn = MemCache.new(self.servers, self.store_options.merge({:namespace => :namespace_versions}))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def increment_version(name)
|
52
|
+
name = name.to_s
|
53
|
+
v = get_version(name)
|
54
|
+
self.ns_versions.set(name, v + 1)
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_version(name)
|
58
|
+
name = name.to_s
|
59
|
+
v = self.ns_versions.get(name)
|
60
|
+
if v.nil?
|
61
|
+
self.ns_versions.set(name, 1)
|
62
|
+
v = 1
|
63
|
+
end
|
64
|
+
v
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: cachetastic
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.0.5
|
7
|
+
date: 2007-12-28 00:00:00 -05:00
|
8
|
+
summary: cachetastic
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
- lib
|
12
|
+
email:
|
13
|
+
homepage:
|
14
|
+
rubyforge_project: magrathea
|
15
|
+
description: "cachetastic was developed by: markbates"
|
16
|
+
autorequire:
|
17
|
+
- cachetastic
|
18
|
+
default_executable:
|
19
|
+
bindir: bin
|
20
|
+
has_rdoc: false
|
21
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 0.0.0
|
26
|
+
version:
|
27
|
+
platform: ruby
|
28
|
+
signing_key:
|
29
|
+
cert_chain:
|
30
|
+
post_install_message:
|
31
|
+
authors:
|
32
|
+
- markbates
|
33
|
+
files:
|
34
|
+
- init.rb
|
35
|
+
- lib/caches/cachetastic_caches_base.rb
|
36
|
+
- lib/caches/cachetastic_caches_page_cache.rb
|
37
|
+
- lib/caches/cachetastic_caches_rails_session_cache.rb
|
38
|
+
- lib/cachetastic.rb
|
39
|
+
- lib/cachetastic_connection.rb
|
40
|
+
- lib/cachetastic_logger.rb
|
41
|
+
- lib/helpers/cachetastic_helpers_active_record.rb
|
42
|
+
- lib/rails_extensions/cachetastic_active_record_base.rb
|
43
|
+
- lib/rails_extensions/cgi_session_cachetastic_store.rb
|
44
|
+
- lib/stores/cachetastic_stores_base.rb
|
45
|
+
- lib/stores/cachetastic_stores_local_memory.rb
|
46
|
+
- lib/stores/cachetastic_stores_memcache.rb
|
47
|
+
- lib/tasks/rubyforge_config.yml
|
48
|
+
test_files: []
|
49
|
+
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
extra_rdoc_files: []
|
53
|
+
|
54
|
+
executables: []
|
55
|
+
|
56
|
+
extensions: []
|
57
|
+
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
dependencies: []
|
61
|
+
|