markbates-cachetastic-three 2.9.9.20090525090948

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/README ADDED
@@ -0,0 +1,75 @@
1
+ =Configuration:
2
+
3
+ # this will dump into the log, configuration info for each cache, as well as the .inspect
4
+ # for each object returned from the cache
5
+ configatron.cachetastic_default_options.debug = false
6
+
7
+ # this is the type of file store to be used for this cache.
8
+ # more adapters can be developed and plugged in as desired
9
+ configatron.cachetastic_default_options.adapter = :local_memory # local_memory | memcache | file | drb | html_file (default: local_memory)
10
+
11
+ # this will marshall objects into and out of the store.
12
+ configatron.cachetastic_default_options.marshall_method = :none # none | yaml | ruby (default: none)
13
+
14
+ # this sets how long objects will live in the cache before they are auto expired.
15
+ configatron.cachetastic_default_options.default_expiry = 86400 # time in seconds (default: 24 hours)
16
+
17
+ # when setting objects into the cache the expiry_swing is +/- to the expiry time.
18
+ # example: if the expiry time is 1 hour, and the swing is 15 minutes,
19
+ # objects will go into the cache with an expiry time sometime between 45 mins and 75 mins.
20
+ configatron.cachetastic_default_options.expiry_swing = 60 * 15 # time in seconds (default: 0)
21
+
22
+ # these options get passed on directly to the store.
23
+ # listed below are options for memcache:
24
+ configatron.cachetastic_default_options.store_options.c_threshold = "10_000"
25
+ configatron.cachetastic_default_options.store_options.compression = true
26
+ configatron.cachetastic_default_options.store_options.debug = false
27
+ configatron.cachetastic_default_options.store_options.readonly = false
28
+ configatron.cachetastic_default_options.store_options.urlencode = false
29
+
30
+ # set the servers to be used for memcache
31
+ configatron.cachetastic_default_options.servers = ["127.0.0.1:11211"] # ip:port used for memcache
32
+
33
+ # listed below are the options for file:
34
+ configatron.cachetastic_default_options.store_options.dir = "/cachetastic/caches"
35
+
36
+ # listed below are the options for drb:
37
+ configatron.cachetastic_default_options.servers = ["druby://127.0.0.1:61676"]
38
+
39
+ # configure logging for this cache
40
+ # n number of logs can be configured for a cache
41
+ log_1 = Logger.new(STDOUT)
42
+ log_1.level = Logger::DEBUG
43
+ log_2 = Logger.new("log/cachetastic.log")
44
+ log_2.level = Logger::ERROR
45
+ configatron.cachetastic_default_options.logger = [log_1, log_2]
46
+
47
+ =Cachetastic::Drb::Server
48
+ If you want to use Drb and the Cachetastic::Adapters::Drb adapter, you'll have to use the Cachetastic::Drb::Server that comes with Cachetastic. Using this server is simple. It gets installed as a binary when you install the Cachetastic gem.
49
+
50
+ $ cachetastic_drb_server # that will start the drb server on the host 127.0.0.1 on the port 61676
51
+
52
+ The server takes to command line parameters: -h <host> -p <port> -v <verbose> -rv <really verbose>
53
+
54
+ =Examples:
55
+
56
+ class MyAwesomeCache < Cachetastic::Caches::Base
57
+ end
58
+
59
+ MyAwesomeCache.set(1, [1,2,3])
60
+ MyAwesomeCache.get(1) # => [1,2,3]
61
+
62
+ class MyAwesomeCache < Cachetastic::Caches::Base
63
+ class << self
64
+ def get(key, x, y)
65
+ super(key) do
66
+ n = x + y
67
+ set(key, n)
68
+ n
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ MyAwesomeCache.get(1, 2, 4) # => 8
75
+ MyAwesomeCache.get(1, 4, 4) # => 8
@@ -0,0 +1,20 @@
1
+ require 'configatron'
2
+ require 'logger'
3
+ require 'activesupport'
4
+ require 'fileutils'
5
+ require 'memcache'
6
+
7
+ Dir.glob(File.join(File.dirname(__FILE__), 'cachetastic', '**/*.rb')).each do |f|
8
+ require File.expand_path(f)
9
+ end
10
+
11
+ configatron.cachetastic.defaults.set_default(:marshal_method, :none)
12
+ configatron.cachetastic.defaults.set_default(:expiry_swing, 0)
13
+ configatron.cachetastic.defaults.set_default(:default_expiry, 86400)
14
+ configatron.cachetastic.defaults.set_default(:debug, true)
15
+ configatron.cachetastic.defaults.set_default(:adapter, Cachetastic::Adapters::LocalMemory)
16
+ log_path = File.join(FileUtils.pwd, 'log', 'cachetastic.log')
17
+ FileUtils.mkdir_p(File.dirname(log_path))
18
+ logger = ::Logger.new(log_path)
19
+ logger.level = ::Logger::DEBUG
20
+ configatron.cachetastic.defaults.set_default(:logger, logger)
@@ -0,0 +1,106 @@
1
+ module Cachetastic
2
+ module Adapters
3
+
4
+ class << self
5
+
6
+ def build(klass)
7
+ adp = klass.to_configatron(:cachetastic).adapter
8
+ if adp.nil?
9
+ adp = configatron.cachetastic.defaults.adapter
10
+ end
11
+ adp.new(klass)
12
+ end
13
+
14
+ end # class << self
15
+
16
+ class Base
17
+
18
+ attr_accessor :klass
19
+
20
+ def initialize(klass)
21
+ self.klass = klass
22
+ configatron.cachetastic.defaults.configatron_keys.each do |key|
23
+ define_accessor(key)
24
+ self.send("#{key}=", configatron.cachetastic.defaults.send(key))
25
+ end
26
+ klass.to_configatron(:cachetastic).configatron_keys.each do |key|
27
+ define_accessor(key)
28
+ self.send("#{key}=", klass.to_configatron(:cachetastic).send(key))
29
+ end
30
+ end
31
+
32
+ # Allows an adapter to transform the key
33
+ # to a safe representation for it's backend.
34
+ # For example, the key: '$*...123()%~q' is not a
35
+ # key for the file system, so the
36
+ # Cachetastic::Adapters::File class should override
37
+ # this to make it safe for the file system.
38
+ def transform_key(key)
39
+ key
40
+ end
41
+
42
+ def valid?
43
+ true
44
+ end
45
+
46
+ def debug?
47
+ return self.debug if self.respond_to?(:debug)
48
+ return false
49
+ end
50
+
51
+ def marshal(value)
52
+ return nil if value.nil?
53
+ case self.marshal_method.to_sym
54
+ when :yaml
55
+ return YAML.dump(value)
56
+ when :ruby
57
+ return Marshal.dump(value)
58
+ else
59
+ return value
60
+ end
61
+ end
62
+
63
+ def unmarshal(value)
64
+ return nil if value.nil?
65
+ case self.marshal_method.to_sym
66
+ when :yaml
67
+ return YAML.load(value)
68
+ when :ruby
69
+ return Marshal.load(value)
70
+ else
71
+ return value
72
+ end
73
+ end
74
+
75
+ private
76
+ # If the expiry time is set to 60 minutes and the expiry_swing time is set to
77
+ # 15 minutes, this method will return a number between 45 minutes and 75 minutes.
78
+ def calculate_expiry_time(expiry_time) # :doc:
79
+ expiry_time = self.default_expiry if expiry_time.nil?
80
+ exp_swing = self.expiry_swing
81
+ if exp_swing && exp_swing != 0
82
+ swing = rand(exp_swing.to_i)
83
+ case rand(2)
84
+ when 0
85
+ expiry_time = (expiry_time.to_i + swing)
86
+ when 1
87
+ expiry_time = (expiry_time.to_i - swing)
88
+ end
89
+ end
90
+ expiry_time
91
+ end
92
+
93
+ def define_accessor(key)
94
+ instance_eval(%{
95
+ def #{key}
96
+ @#{key}
97
+ end
98
+ def #{key}=(x)
99
+ @#{key} = x
100
+ end
101
+ })
102
+ end
103
+
104
+ end # Base
105
+ end # Adapters
106
+ end # Cachetastic
@@ -0,0 +1,53 @@
1
+ module Cachetastic
2
+ module Adapters
3
+ class File < Cachetastic::Adapters::Base
4
+
5
+ def initialize(klass)
6
+ define_accessor(:storage_path)
7
+ self.storage_path = ::File.join(FileUtils.pwd, 'cachetastic')
8
+ super
9
+ self.marshal_method = :yaml if self.marshal_method == :none
10
+ @_file_paths = {}
11
+ end
12
+
13
+ def get(key, &block)
14
+ path = file_path(key)
15
+ val = nil
16
+ val = ::File.read(path) if ::File.exists?(path)
17
+ return val
18
+ end # get
19
+
20
+ def set(key, value, expiry_time = nil)
21
+ so = Cachetastic::Cache::StoreObject.new(key, value, calculate_expiry_time(expiry_time).from_now)
22
+ path = file_path(key)
23
+ ::File.open(path, 'w') {|f| f.write marshal(so)}
24
+ value
25
+ end # set
26
+
27
+ def delete(key)
28
+ FileUtils.rm(file_path(key))
29
+ end # delete
30
+
31
+ def expire_all
32
+ @_file_paths = {}
33
+ ::FileUtils.rm_rf(::File.join(self.storage_path, klass.name.underscore))
34
+ return nil
35
+ end # expire_all
36
+
37
+ def transform_key(key)
38
+ key.to_s.hexdigest
39
+ end
40
+
41
+ def file_path(key)
42
+ path = @_file_paths[key]
43
+ if path.nil?
44
+ path = ::File.join(self.storage_path, klass.name.underscore, transform_key(key).scan(/(.{1,4})/).flatten, 'cache.data')
45
+ @_file_paths[key] = path
46
+ FileUtils.mkdir_p(::File.dirname(path))
47
+ end
48
+ return path
49
+ end
50
+
51
+ end # File
52
+ end # Adapters
53
+ end # Cachetastic
@@ -0,0 +1,31 @@
1
+ module Cachetastic
2
+ module Adapters
3
+ class LocalMemory < Cachetastic::Adapters::Base
4
+
5
+ def initialize(klass)
6
+ super
7
+ @_store = {}
8
+ end
9
+
10
+ def get(key, &block)
11
+ @_store[key]
12
+ end # get
13
+
14
+ def set(key, value, expiry_time = nil)
15
+ so = Cachetastic::Cache::StoreObject.new(key, value, calculate_expiry_time(expiry_time).from_now)
16
+ @_store[key] = marshal(so)
17
+ value
18
+ end # set
19
+
20
+ def delete(key)
21
+ @_store.delete(key)
22
+ end # delete
23
+
24
+ def expire_all
25
+ @_store = {}
26
+ return nil
27
+ end # expire_all
28
+
29
+ end # LocalMemory
30
+ end # Adapters
31
+ end # Cachetastic
@@ -0,0 +1,93 @@
1
+ module Cachetastic
2
+ module Adapters
3
+ class Memcached < Cachetastic::Adapters::Base
4
+
5
+ def initialize(klass)
6
+ # puts "initialize: #{klass}"
7
+ define_accessor(:servers)
8
+ define_accessor(:mc_options)
9
+ define_accessor(:delete_delay)
10
+ self.delete_delay = 0
11
+ self.servers = ['127.0.0.1:11211']
12
+ self.mc_options = {:c_threshold => 10_000,
13
+ :compression => true,
14
+ :debug => false,
15
+ :readonly => false,
16
+ :urlencode => false}
17
+ super
18
+ connection
19
+ end
20
+
21
+ def get(key, &block)
22
+ connection.get(transform_key(key), false)
23
+ end # get
24
+
25
+ def set(key, value, expiry_time = 0)
26
+ connection.set(transform_key(key), marshal(value), calculate_expiry_time(expiry_time), false)
27
+ end # set
28
+
29
+ def delete(key)
30
+ connection.delete(transform_key(key), self.delete_delay)
31
+ end # delete
32
+
33
+ def expire_all
34
+ increment_version
35
+ @_mc_connection = nil
36
+ return nil
37
+ end # expire_all
38
+
39
+ def transform_key(key)
40
+ key.to_s.hexdigest
41
+ end
42
+
43
+ def valid?
44
+ return false if @_mc_connection.nil?
45
+ return false unless @_mc_connection.active?
46
+ return true
47
+ end
48
+
49
+ private
50
+ def connection
51
+ unless @_mc_connection && valid? && @_ns_version == get_version
52
+ @_mc_connection = MemCache.new(self.servers, self.mc_options.merge(:namespace => namespace))
53
+ end
54
+ @_mc_connection
55
+ end
56
+
57
+ def ns_connection
58
+ unless @_ns_connection
59
+ @_ns_connection = MemCache.new(self.servers, self.mc_options.merge(:namespace => :namespace_versions))
60
+ end
61
+ @_ns_connection
62
+ end
63
+
64
+ def increment_version
65
+ name = self.klass.name
66
+ v = get_version
67
+ ns_connection.set(name, v + 1)
68
+ end
69
+
70
+ def get_version
71
+ name = self.klass.name
72
+ v = ns_connection.get(name)
73
+ if v.nil?
74
+ ns_connection.set(name, 1)
75
+ v = 1
76
+ end
77
+ v
78
+ end
79
+
80
+ def namespace
81
+ @_ns_version = get_version
82
+ "#{self.klass.name}.#{@_ns_version}"
83
+ end
84
+
85
+ end # Memcached
86
+ end # Adapters
87
+ end # Cachetastic
88
+
89
+ # c_threshold: 10_000
90
+ # compression: true
91
+ # debug: false
92
+ # readonly: false
93
+ # urlencode: false
@@ -0,0 +1,99 @@
1
+ module Cachetastic
2
+ class Cache
3
+
4
+ class << self
5
+
6
+ def get(key, &block)
7
+ do_with_logging(:get, key) do
8
+ val = self.adapter.get(key, &block)
9
+ handle_store_object(key, adapter.unmarshal(val), &block)
10
+ end
11
+ end # get
12
+
13
+ def set(key, value, expiry_time = nil)
14
+ do_with_logging(:set, key) do
15
+ self.adapter.set(key, value, expiry_time)
16
+ end
17
+ end # set
18
+
19
+ def delete(key)
20
+ do_with_logging(:delete, key) do
21
+ self.adapter.delete(key)
22
+ nil
23
+ end
24
+ end # delete
25
+
26
+ def expire_all
27
+ do_with_logging(:expire_all, nil) do
28
+ self.adapter.expire_all
29
+ nil
30
+ end
31
+ end # expire_all
32
+
33
+ def adapter
34
+ unless @_adapter && @_adapter.valid?
35
+ @_adapter = Cachetastic::Adapters.build(cache_klass)
36
+ end
37
+ @_adapter
38
+ end # adapter
39
+
40
+ def clear_adapter!
41
+ @_adapter = nil
42
+ end
43
+
44
+ def cache_klass
45
+ self
46
+ end
47
+
48
+ def logger
49
+ unless @_logger
50
+ @_logger = Cachetastic::Logger.new(adapter.logger)
51
+ end
52
+ @_logger
53
+ end
54
+
55
+ private
56
+ def handle_store_object(key, val, &block)
57
+ if val.is_a?(Cachetastic::Cache::StoreObject)
58
+ if val.expired?
59
+ self.delete(key)
60
+ val = nil
61
+ else
62
+ val = val.value
63
+ end
64
+ end
65
+
66
+ if val.respond_to?(:empty?)
67
+ val = nil if val.empty?
68
+ elsif val.respond_to?(:blank?)
69
+ val = nil if val.blank?
70
+ end
71
+ return val unless val.nil?
72
+
73
+ val = yield if block_given?
74
+ return val
75
+ end
76
+
77
+ def do_with_logging(action, key)
78
+ if adapter.debug?
79
+ start_time = Time.now
80
+ logger.debug(:starting, action, cache_klass.name, key)
81
+ res = yield if block_given?
82
+ end_time = Time.now
83
+ str = ''
84
+ unless res.nil?
85
+ str = "[#{res.class.name}]"
86
+ str << "\t[Size = #{res.size}]" if res.respond_to? :size
87
+ str << "\t" << res.inspect
88
+ end
89
+ logger.debug(:finished, action, cache_klass.name, key, (end_time - start_time), str)
90
+ return res
91
+ else
92
+ return yield if block_given?
93
+ end
94
+ end
95
+
96
+ end # class << self
97
+
98
+ end # Cache
99
+ end # Cachetastic
@@ -0,0 +1,202 @@
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
+ c_name = "Cachetastic::Cacheable::#{n.gsub('::', '_')}Cache"
43
+ begin
44
+ return c_name.constantize
45
+ rescue NameError => e
46
+ eval %{
47
+ class #{c_name} < Cachetastic::Cache
48
+
49
+ def self.cache_klass
50
+ #{n}
51
+ end
52
+
53
+ end
54
+ }
55
+ return c_name.constantize
56
+ end
57
+
58
+ end
59
+
60
+ # How much did I want to call this method cache?? It originally was that, but
61
+ # in Rails 2.0 they decided to use that name, so I had to rename this method.
62
+ # This method will attempt to get an object from the cache for a given key.
63
+ # If the object is nil and a block is given the block will be run, and the results
64
+ # of the block will be automatically cached.
65
+ #
66
+ # Example:
67
+ # class Person
68
+ # include Cachetastic::Cacheable
69
+ # attr_accessor :name
70
+ # def cachetastic_key
71
+ # self.name
72
+ # end
73
+ # def always_the_same(x,y)
74
+ # cacher("always_the_same") do
75
+ # x + y
76
+ # end
77
+ # end
78
+ # end
79
+ #
80
+ # Person.new.always_the_same(1,2) # => 3
81
+ # Person.new.always_the_same(2,2) # => 3
82
+ # Person.new.always_the_same(3,3) # => 3
83
+ # Person.cacher("always_the_same") # => 3
84
+ # Person.get_from_cache("always_the_same") # => 3
85
+ # Cachetastic::Cacheable::PersonCache.get("always_the_same") # => 3
86
+ #
87
+ # Person.cacher("say_hi") {"Hi There"} # => "Hi There"
88
+ # Person.get_from_cache("say_hi") # => "Hi There"
89
+ # Cachetastic::Cacheable::PersonCache.get("say_hi") # => "Hi There"
90
+ def cacher(key, expiry = 0)
91
+ cache_class.get(key) do
92
+ if block_given?
93
+ res = yield
94
+ cache_class.set(key, res, expiry)
95
+ end
96
+ end
97
+ end
98
+
99
+ # Expires the entire cache associated with this objects's cache.
100
+ #
101
+ # Example:
102
+ # class Person
103
+ # include Cachetastic::Cacheable
104
+ # attr_accessor :name
105
+ # def cachetastic_key
106
+ # self.name
107
+ # end
108
+ # end
109
+ #
110
+ # Person.set_into_cache(1, "one")
111
+ # Person.get_from_cache(1) # => "one"
112
+ # Person.expire_all
113
+ # Person.get_from_cache(1) # => nil
114
+ # Person.set_into_cache(1, "one")
115
+ # Person.get_from_cache(1) # => "one"
116
+ # Cachetastic::Cacheable::PersonCache.expire_all
117
+ # Person.get_from_cache(1) # => nil
118
+ def expire_all
119
+ cache_class.expire_all
120
+ end
121
+ end
122
+
123
+ # --------------------------
124
+ # Instance only methods:
125
+
126
+ # Unless the object's cachetastic_key method returns nil this method will store
127
+ # the object in the cache using the object's cachetastic_key as the key.
128
+ # You *MUST* create an instance level method called cachetastic_key and
129
+ # have it return a valid key! If you return nil from the cachetastic_key method or you will not be
130
+ # able to use the cache_self and uncache_self methods.
131
+ #
132
+ # Example:
133
+ # class Person
134
+ # include Cachetastic::Cacheable
135
+ # attr_accessor :name
136
+ # def cachetastic_key
137
+ # self.name
138
+ # end
139
+ # end
140
+ #
141
+ # Person.get_from_cache("Mark Bates") # => nil
142
+ # p = Person.new
143
+ # p.name = "Mark Bates"
144
+ # p.cache_self
145
+ # Person.get_from_cache("Mark Bates") # => "Mark Bates"
146
+ def cache_self
147
+ cache_class.set(self.cachetastic_key, self) unless self.cachetastic_key.nil?
148
+ end
149
+
150
+ # Unless the object's cachetastic_key method returns nil this method will delete
151
+ # the object in the cache using the object's cachetastic_key as the key.
152
+ # You *MUST* create an instance level method called cachetastic_key and
153
+ # have it return a valid key! If you return nil from the cachetastic_key method or you will not be
154
+ # able to use the cache_self and uncache_self methods.
155
+ #
156
+ # Example:
157
+ # class Person
158
+ # include Cachetastic::Cacheable
159
+ # attr_accessor :name
160
+ # def cachetastic_key
161
+ # self.name
162
+ # end
163
+ # end
164
+ #
165
+ # Person.get_from_cache("Mark Bates") # => nil
166
+ # p = Person.new
167
+ # p.name = "Mark Bates"
168
+ # p.cache_self
169
+ # Person.get_from_cache("Mark Bates") # => "Mark Bates"
170
+ # p.uncache_self
171
+ # Person.get_from_cache("Mark Bates") # => nil
172
+ def uncache_self
173
+ cache_class.delete(self.cachetastic_key) unless self.cachetastic_key.nil?
174
+ end
175
+
176
+ # --------------------------
177
+
178
+ def self.included(klass) # :nodoc:
179
+ klass.send(:include, ClassAndInstanceMethods)
180
+ klass.extend(ClassOnlyMethods)
181
+ klass.extend(ClassAndInstanceMethods)
182
+ end
183
+
184
+ module ClassOnlyMethods
185
+ # Returns an object from the cache for a given key.
186
+ def get_from_cache(key, &block)
187
+ cache_class.get(key, &block)
188
+ end
189
+
190
+ # Deletes an object from the cache for a given key.
191
+ def delete_from_cache(key)
192
+ cache_class.delete(key)
193
+ end
194
+
195
+ # Sets an object into the cache for a given key.
196
+ def set_into_cache(key, value, expiry = 0)
197
+ cache_class.set(key, value, expiry)
198
+ end
199
+ end # ClassMethods
200
+
201
+ end # Cacheable
202
+ end # Cachetastic
@@ -0,0 +1,8 @@
1
+ require 'digest'
2
+ class String # :nodoc:
3
+
4
+ def hexdigest # :nodoc:
5
+ Digest::SHA1.hexdigest(self)
6
+ end
7
+
8
+ end
@@ -0,0 +1,37 @@
1
+ # This class handles logging for the caches and their adapters.
2
+ module Cachetastic
3
+ class Logger
4
+
5
+ # attr_accessor :options
6
+ # attr_accessor :cache_name
7
+ attr_accessor :loggers
8
+
9
+ def initialize(*loggers)
10
+ @loggers = [loggers].flatten
11
+ end
12
+
13
+ LOG_LEVELS = [:fatal, :error, :warn, :info, :debug]
14
+
15
+ LOG_LEVELS.each do |level|
16
+ define_method(level) do |*args|
17
+ lm = "[CACHE] [#{level.to_s.upcase}]\t#{Time.now.strftime("%m/%d/%y %H:%M:%S")}"
18
+ exs = []
19
+ args.each do |arg|
20
+ if arg.is_a?(Exception)
21
+ exs << arg
22
+ continue
23
+ end
24
+ lm << "\t" << arg.to_s
25
+ end
26
+ exs.each do |ex|
27
+ lm << "\n#{ex.message}\n" << ex.backtrace.join("\n")
28
+ end
29
+ # puts "lm: #{lm}"
30
+ self.loggers.each do |log|
31
+ log.send(level, lm)
32
+ end
33
+ end
34
+ end
35
+
36
+ end # Logger
37
+ end # Cachetastic
@@ -0,0 +1,22 @@
1
+ module Cachetastic
2
+ class Cache
3
+
4
+ class StoreObject # :nodoc:
5
+ attr_accessor :expires_at
6
+ attr_accessor :key
7
+ attr_accessor :value
8
+
9
+ def initialize(key, value, expires_at)
10
+ self.key = key
11
+ self.value = value
12
+ self.expires_at = expires_at
13
+ end
14
+
15
+ def expired?
16
+ return Time.now > self.expires_at
17
+ end
18
+
19
+ end # StoreObject
20
+
21
+ end # Cache
22
+ end # Cachetastic
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: markbates-cachetastic-three
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.9.9.20090525090948
5
+ platform: ruby
6
+ authors:
7
+ - Mark Bates
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-25 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: configatron
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.3.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: memcache-client
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.5.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: activesupport
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.2.2
44
+ version:
45
+ description: A very simple, yet very powerful caching framework for Ruby.
46
+ email: mark@mackframework.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - README
53
+ files:
54
+ - lib/cachetastic/adapters/base.rb
55
+ - lib/cachetastic/adapters/file.rb
56
+ - lib/cachetastic/adapters/local_memory.rb
57
+ - lib/cachetastic/adapters/memcached.rb
58
+ - lib/cachetastic/cache.rb
59
+ - lib/cachetastic/cacheable.rb
60
+ - lib/cachetastic/extensions/string.rb
61
+ - lib/cachetastic/logger.rb
62
+ - lib/cachetastic/store_object.rb
63
+ - lib/cachetastic.rb
64
+ - README
65
+ has_rdoc: true
66
+ homepage: http://www.mackframework.com
67
+ post_install_message:
68
+ rdoc_options: []
69
+
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
84
+ requirements: []
85
+
86
+ rubyforge_project: cachetastic
87
+ rubygems_version: 1.2.0
88
+ signing_key:
89
+ specification_version: 2
90
+ summary: A very simple, yet very powerful caching framework for Ruby.
91
+ test_files: []
92
+