cachetastic 2.1.4 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/LICENSE +21 -0
  2. data/README +57 -43
  3. data/doc/classes/Cachetastic/Adapters.html +180 -0
  4. data/doc/classes/Cachetastic/Adapters/Base.html +206 -123
  5. data/doc/classes/Cachetastic/Adapters/File.html +17 -130
  6. data/doc/classes/Cachetastic/Adapters/LocalMemory.html +7 -228
  7. data/doc/classes/Cachetastic/Adapters/Memcached.html +193 -0
  8. data/doc/classes/Cachetastic/Cache.html +425 -0
  9. data/doc/classes/Cachetastic/Cacheable.html +26 -30
  10. data/doc/classes/Cachetastic/Cacheable/ClassAndInstanceMethods.html +66 -62
  11. data/doc/classes/Cachetastic/Cacheable/ClassOnlyMethods.html +30 -30
  12. data/doc/classes/Cachetastic/Logger.html +31 -33
  13. data/doc/created.rid +1 -1
  14. data/doc/files/{lib/cachetastic/adapters/html_file_rb.html → LICENSE.html} +29 -34
  15. data/doc/files/README.html +91 -57
  16. data/doc/files/lib/cachetastic/adapters/base_rb.html +1 -39
  17. data/doc/files/lib/cachetastic/adapters/file_rb.html +1 -21
  18. data/doc/files/lib/cachetastic/adapters/local_memory_rb.html +1 -9
  19. data/doc/files/lib/cachetastic/{ruby_extensions/kernel_rb.html → adapters/memcached_rb.html} +4 -4
  20. data/doc/files/lib/cachetastic/{ruby_extensions/string_rb.html → cache_rb.html} +5 -5
  21. data/doc/files/lib/cachetastic/cacheable_rb.html +1 -1
  22. data/doc/files/lib/cachetastic/{caches/base_rb.html → extensions/string_rb.html} +5 -5
  23. data/doc/files/lib/cachetastic/logger_rb.html +1 -7
  24. data/doc/files/lib/cachetastic/{adapters/store_object_rb.html → store_object_rb.html} +3 -3
  25. data/doc/files/lib/cachetastic_rb.html +4 -95
  26. data/doc/fr_class_index.html +3 -15
  27. data/doc/fr_file_index.html +5 -16
  28. data/doc/fr_method_index.html +26 -78
  29. data/lib/cachetastic.rb +16 -70
  30. data/lib/cachetastic/adapters/base.rb +178 -76
  31. data/lib/cachetastic/adapters/file.rb +63 -46
  32. data/lib/cachetastic/adapters/local_memory.rb +36 -67
  33. data/lib/cachetastic/adapters/memcached.rb +114 -0
  34. data/lib/cachetastic/cache.rb +165 -0
  35. data/lib/cachetastic/cacheable.rb +19 -15
  36. data/lib/cachetastic/extensions/string.rb +8 -0
  37. data/lib/cachetastic/logger.rb +41 -41
  38. data/lib/cachetastic/store_object.rb +22 -0
  39. metadata +43 -64
  40. data/bin/cachetastic_drb_server +0 -115
  41. data/doc/classes/ActiveRecord/Base.html +0 -194
  42. data/doc/classes/CGI/Session/CachetasticStore.html +0 -124
  43. data/doc/classes/Cachetastic/Adapters/Drb.html +0 -332
  44. data/doc/classes/Cachetastic/Adapters/FileBase.html +0 -309
  45. data/doc/classes/Cachetastic/Adapters/HtmlFile.html +0 -224
  46. data/doc/classes/Cachetastic/Adapters/Memcache.html +0 -498
  47. data/doc/classes/Cachetastic/Caches/Base.html +0 -643
  48. data/doc/classes/Cachetastic/Caches/Base/RegisteredCaches.html +0 -179
  49. data/doc/classes/Cachetastic/Caches/MackSessionCache.html +0 -119
  50. data/doc/classes/Cachetastic/Caches/PageCache.html +0 -121
  51. data/doc/classes/Cachetastic/Caches/RailsSessionCache.html +0 -154
  52. data/doc/classes/Cachetastic/Connection.html +0 -212
  53. data/doc/classes/Cachetastic/Errors/UnsupportedAdapter.html +0 -146
  54. data/doc/classes/Object.html +0 -222
  55. data/doc/classes/String.html +0 -172
  56. data/doc/files/lib/cachetastic/adapters/drb_rb.html +0 -115
  57. data/doc/files/lib/cachetastic/adapters/file_base_rb.html +0 -109
  58. data/doc/files/lib/cachetastic/adapters/memcache_rb.html +0 -127
  59. data/doc/files/lib/cachetastic/caches/mack_session_cache_rb.html +0 -107
  60. data/doc/files/lib/cachetastic/caches/page_cache_rb.html +0 -109
  61. data/doc/files/lib/cachetastic/caches/rails_session_cache_rb.html +0 -107
  62. data/doc/files/lib/cachetastic/connection_rb.html +0 -107
  63. data/doc/files/lib/cachetastic/errors/unsupported_adapter_rb.html +0 -101
  64. data/doc/files/lib/cachetastic/rails_extensions/active_record_base_rb.html +0 -101
  65. data/doc/files/lib/cachetastic/rails_extensions/cgi_session_store_rb.html +0 -109
  66. data/doc/files/lib/cachetastic/ruby_extensions/object_rb.html +0 -101
  67. data/lib/cachetastic/adapters/drb.rb +0 -51
  68. data/lib/cachetastic/adapters/file_base.rb +0 -86
  69. data/lib/cachetastic/adapters/html_file.rb +0 -68
  70. data/lib/cachetastic/adapters/memcache.rb +0 -114
  71. data/lib/cachetastic/adapters/store_object.rb +0 -28
  72. data/lib/cachetastic/caches/base.rb +0 -238
  73. data/lib/cachetastic/caches/mack_session_cache.rb +0 -3
  74. data/lib/cachetastic/caches/page_cache.rb +0 -6
  75. data/lib/cachetastic/caches/rails_session_cache.rb +0 -12
  76. data/lib/cachetastic/connection.rb +0 -24
  77. data/lib/cachetastic/errors/unsupported_adapter.rb +0 -7
  78. data/lib/cachetastic/rails_extensions/active_record_base.rb +0 -24
  79. data/lib/cachetastic/rails_extensions/cgi_session_store.rb +0 -59
  80. data/lib/cachetastic/ruby_extensions/kernel.rb +0 -25
  81. data/lib/cachetastic/ruby_extensions/object.rb +0 -22
  82. data/lib/cachetastic/ruby_extensions/string.rb +0 -15
  83. data/test/active_record_test.rb +0 -89
  84. data/test/cacheable_test.rb +0 -88
  85. data/test/cachetastic_unit_test.rb +0 -74
  86. data/test/config.rb +0 -30
  87. data/test/drb_adapter_test.rb +0 -14
  88. data/test/file_adapter_test.rb +0 -49
  89. data/test/memcache_adapter_test.rb +0 -18
  90. data/test/test_helper.rb +0 -75
@@ -1,68 +0,0 @@
1
- # This adapter uses the file system as it's backing.
2
- # Caches are stored in files called index.html.
3
- # At the beginning of the html the following html comments are pre-pended:
4
- # <!-- cachetastic: expires_at: Fri Feb 01 20:51:45 -0500 2008 -->
5
- # <!-- cachetastic: key: /channels/1-arts-humanities -->
6
- # Obviously the expires_at date will be the ACTUAL expire date,
7
- # same goes for the key.
8
- # The configuration for this should look something like this:
9
- # my_awesome_cache_options:
10
- # debug: false
11
- # adapter: html_file
12
- # marshall_method: none
13
- # default_expiry: <%= 24.hours %>
14
- # store_options:
15
- # dir: /usr/local/caches/
16
- # logging:
17
- # logger_1:
18
- # type: file
19
- # file: log/file_store_cache.log
20
- require 'time'
21
- class Cachetastic::Adapters::HtmlFile < Cachetastic::Adapters::FileBase
22
-
23
- def get(key)
24
- full_path = full_path_from_dir(get_key_directoy(key, false))
25
- return nil unless File.exists?(full_path)
26
- so = html_to_store_object(File.open(full_path).read)
27
- if so
28
- if so.invalid?
29
- self.delete(key)
30
- return nil
31
- end
32
- return so.value
33
- end
34
- return nil
35
- end
36
-
37
- def set(key, value, expiry = 0)
38
- so = Cachetastic::Adapters::StoreObject.new(key.to_s, value, expiry)
39
- File.open(full_path_from_key(key), "w") do |f|
40
- f.puts store_object_to_html(so)
41
- end
42
- end
43
-
44
- protected
45
- def store_file_name
46
- return STORE_FILE_NAME
47
- end
48
-
49
- private
50
- def html_to_store_object(html)
51
- key = html.match(/<!-- cachetastic: key: (.*) -->/).captures.first
52
- expires_at = html.match(/<!-- cachetastic: expires_at: (.*) -->/).captures.first
53
- html.gsub!(/<!-- cachetastic: key: .* -->/, '')
54
- html.gsub!(/<!-- cachetastic: expires_at: .* -->/, '')
55
- so = Cachetastic::Adapters::StoreObject.new(key, html, 0)
56
- so.expires_at = Time.parse(expires_at)
57
- so
58
- end
59
-
60
- def store_object_to_html(so)
61
- x = so.value
62
- x << "\n<!-- cachetastic: expires_at: #{so.expires_at} -->"
63
- x << "\n<!-- cachetastic: key: #{so.key} -->"
64
- end
65
-
66
- STORE_FILE_NAME = "index.html"
67
-
68
- end
@@ -1,114 +0,0 @@
1
- # This adapter uses Memcache as it's backing.
2
- # The configuration for this should look something like this:
3
- # my_awesome_cache_options:
4
- # debug: false
5
- # adapter: memcache
6
- # marshall_method: none
7
- # default_expiry: <%= 24.hours %>
8
- # store_options:
9
- # c_threshold: 10_000
10
- # compression: true
11
- # debug: false
12
- # readonly: false
13
- # urlencode: false
14
- # logging:
15
- # logger_1:
16
- # type: file
17
- # file: log/memcached.log
18
- # servers:
19
- # - 127.0.0.1:11211
20
- class Cachetastic::Adapters::Memcache < Cachetastic::Adapters::Base
21
-
22
- def setup
23
- self.conn = MemCache.new([configuration.servers].flatten, configuration.store_options.to_hash.merge({:namespace => self.namespace}))
24
- self.version = self.get_version(self.name)
25
- end
26
-
27
- def set(key, value, expiry = 0, raw = false)
28
- self.conn.set(key, value, expiry, raw)
29
- end
30
-
31
- def delete(key, delay = 0)
32
- self.conn.delete(key, delay)
33
- end
34
-
35
- def get(key, raw = false)
36
- self.conn.get(key, raw)
37
- end
38
-
39
- def expire_all
40
- self.increment_version(self.name)
41
- end
42
-
43
- def inspect
44
- self.conn.inspect + " <version: #{self.version}> #{self.conn.stats.inspect}"
45
- end
46
-
47
- def valid?
48
- begin
49
- return (self.conn.active? && self.version == self.get_version(self.name))
50
- rescue Exception => e
51
- puts e.message
52
- puts e.backtrace.join("\n")
53
- return false
54
- end
55
- end
56
-
57
- def stats
58
- super
59
- begin
60
- puts "Memcache stats for all caches:"
61
- memc = self.conn
62
- puts Kernel.pp_to_s(memc.stats)
63
- paths = `sh -c 'echo $PATH'`
64
- paths = paths.split(':')
65
- memcached_tool_found = false
66
- paths.each do |path|
67
- cmd_path = File.expand_path(File.join(path,'memcached_tool'))
68
- if File.exists?(cmd_path)
69
- memcached_tool_found = true
70
- break
71
- end
72
- end
73
- if memcached_tool_found
74
- configuration.memcache_servers.each do |server|
75
- puts `memcached_tool #{server}`
76
- end
77
- end
78
- rescue
79
- end
80
- puts ""
81
- end
82
-
83
- protected
84
- attr_accessor :conn
85
- attr_accessor :version
86
-
87
- def namespace
88
- v = self.get_version(self.name)
89
- return "#{name}.#{v}"
90
- end
91
-
92
- def ns_versions
93
- ivar_cache do
94
- ns_conn = MemCache.new([configuration.servers].flatten, configuration.store_options.to_hash.merge({:namespace => :namespace_versions}))
95
- end
96
- end
97
-
98
- def increment_version(name)
99
- name = name.to_s
100
- v = get_version(name)
101
- self.ns_versions.set(name, v + 1)
102
- end
103
-
104
- def get_version(name)
105
- name = name.to_s
106
- v = self.ns_versions.get(name)
107
- if v.nil?
108
- self.ns_versions.set(name, 1)
109
- v = 1
110
- end
111
- v
112
- end
113
-
114
- end
@@ -1,28 +0,0 @@
1
- class Cachetastic::Adapters::StoreObject #:nodoc:#
2
- attr_accessor :key
3
- attr_accessor :value
4
- attr_accessor :expires_at
5
-
6
- def initialize(key, value, expiry)
7
- self.key = key
8
- self.value = value
9
- begin
10
- self.expires_at = (Time.now + (expiry == 0 ? (31536000) : expiry)) # 31536000 = one year
11
- rescue RangeError => e
12
- self.expires_at = Time.at(expiry)
13
- end
14
- # puts "now: #{Time.now}"
15
- # puts "expiry: #{expiry}"
16
- # puts "expires_at: #{self.expires_at}"
17
- end
18
-
19
- def size
20
- return self.value.size if self.value.respond_to?(:size)
21
- -1
22
- end
23
-
24
- def invalid?
25
- Time.now >= self.expires_at
26
- end
27
-
28
- end
@@ -1,238 +0,0 @@
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