cachetastic 1.0.5
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/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
|
+
|