ngmoco-cache-money 0.2.9 → 0.2.10

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/UNSUPPORTED_FEATURES CHANGED
@@ -7,7 +7,6 @@
7
7
  * attr_readonly - no technical obstacle, just not yet supported
8
8
  * attributes before typecast behave unpredictably - hard to support
9
9
  * ActiveRecord::Rollback is unsupported - the exception gets swallowed so there isn't an opportunity to rollback the cache transaction - not hard to support
10
- * Named bind variables :conditions => ["name = :name", { :name => "37signals!" }] - not hard to support
11
10
  * printf style binds: :conditions => ["name = '%s'", "37signals!"] - not too hard to support
12
11
  * objects as attributes that are serialized. story.title = {:foo => :bar}; customer.balance = Money.new(...) - these could be coerced using Column#type_cast?
13
12
 
data/lib/cash/lock.rb CHANGED
@@ -2,8 +2,8 @@ module Cash
2
2
  class Lock
3
3
  class Error < RuntimeError; end
4
4
 
5
- INITIAL_WAIT = 1
6
- DEFAULT_RETRY = 5
5
+ INITIAL_WAIT = 2
6
+ DEFAULT_RETRY = 8
7
7
  DEFAULT_EXPIRY = 30
8
8
 
9
9
  def initialize(cache)
@@ -27,10 +27,10 @@ module Cash
27
27
  retries.times do |count|
28
28
  response = @cache.add("lock/#{key}", Process.pid, lock_expiry)
29
29
  return if response == "STORED\r\n"
30
- raise Error if count == retries - 1
31
30
  exponential_sleep(count, initial_wait) unless count == retries - 1
32
31
  end
33
- raise Error, "Couldn't acquire memcache lock for: #{key}"
32
+ debug_lock(key)
33
+ raise Error, "Couldn't acquire memcache lock for: #{key} server: #{@cache.get_server_for_key(key)}"
34
34
  end
35
35
 
36
36
  def release_lock(key)
@@ -47,5 +47,10 @@ module Cash
47
47
  @cache.get("lock/#{key}") == Process.pid
48
48
  end
49
49
 
50
+ def debug_lock(key)
51
+ @cache.logger.warn("#{@cache.get("lock/#{key}")}") if @cache.respond_to?(:logger) && @cache.logger.respond_to?(:warn)
52
+ rescue
53
+ @cache.logger.warn("#{$!}") if @cache.respond_to?(:logger) && @cache.logger.respond_to?(:warn)
54
+ end
50
55
  end
51
56
  end
@@ -119,7 +119,15 @@ module Cash
119
119
  conditions.split(AND).inject([]) do |indices, condition|
120
120
  matched, table_name, column_name, sql_value = *(KEY_EQ_VALUE.match(condition))
121
121
  if matched
122
- value = sql_value == '?' ? values.shift : columns_hash[column_name].type_cast(sql_value)
122
+ # value = sql_value == '?' ? values.shift : columns_hash[column_name].type_cast(sql_value)
123
+ if sql_value == '?'
124
+ value = values.shift
125
+ elsif sql_value[0..0] == ':' && values && values.count > 0 && values[0].is_a?(Hash)
126
+ symb = sql_value[1..-1].to_sym
127
+ value = columns_hash[column_name].type_cast(values[0][symb])
128
+ else
129
+ value = columns_hash[column_name].type_cast(sql_value)
130
+ end
123
131
  indices << [column_name, value]
124
132
  else
125
133
  return nil
@@ -10,14 +10,14 @@
10
10
  ####### they have MemCache installed (don't need the wrapper)
11
11
  if defined? MemCache
12
12
 
13
- Rails.logger.info("cache-money: MemCache installed")
13
+ Rails.logger.info("cache-money: MemCache installed") if defined? Rails
14
14
  #TODO add logging?
15
15
  class MemcachedWrapper < ::MemCache
16
16
  end
17
17
 
18
18
  ########## they have Memcached installed (do need the wrapper)
19
19
  elsif defined? Memcached
20
- Rails.logger.info("cache-money: Memcached installed")
20
+ Rails.logger.info("cache-money: Memcached installed") if defined? Rails
21
21
 
22
22
  class Memcached
23
23
  alias :get_multi :get #:nodoc:
@@ -69,20 +69,25 @@ class MemcachedWrapper < ::Memcached
69
69
 
70
70
  # Wraps Memcached::Rails#add to return a text string - for cache money
71
71
  def add(key, value, ttl=@default_ttl, raw=false)
72
+ logger.debug("Memcached add: #{key.inspect}") if logger && @debug
72
73
  super(key, value, ttl, !raw)
74
+ logger.debug("Memcached hit: #{key.inspect}") if logger && @debug
73
75
  stored
74
76
  rescue Memcached::NotStored
77
+ logger.debug("Memcached miss: #{key.inspect}") if logger && @debug
75
78
  not_stored
76
79
  rescue Memcached::Error
77
- log_error($!)
78
80
  log_error($!) if logger
79
81
  not_stored
80
82
  end
81
83
 
82
84
  def replace(key, value, ttl = @default_ttl, raw = false)
85
+ logger.debug("Memcached replace: #{key.inspect}") if logger && @debug
83
86
  super(key, value, ttl, !raw)
87
+ logger.debug("Memcached hit: #{key.inspect}") if logger && @debug
84
88
  stored
85
89
  rescue Memcached::NotStored
90
+ logger.debug("Memcached miss: #{key.inspect}") if logger && @debug
86
91
  not_stored
87
92
  rescue Memcached::Error
88
93
  log_error($!) if logger
@@ -122,9 +127,12 @@ class MemcachedWrapper < ::Memcached
122
127
 
123
128
  # Wraps Memcached#cas so that it doesn't raise. Doesn't set anything if no value is present.
124
129
  def cas(key, ttl=@default_ttl, raw=false, &block)
130
+ logger.debug("Memcached cas: #{key.inspect}") if logger && @debug
125
131
  super(key, ttl, !raw, &block)
132
+ logger.debug("Memcached hit: #{key.inspect}") if logger && @debug
126
133
  stored
127
134
  rescue Memcached::NotFound
135
+ logger.debug("Memcached miss: #{key.inspect}") if logger && @debug
128
136
  rescue TypeError
129
137
  log_error($!) if logger
130
138
  delete(key)
@@ -138,7 +146,13 @@ class MemcachedWrapper < ::Memcached
138
146
 
139
147
  def get_multi(*keys)
140
148
  keys.flatten!
141
- super(keys, true)
149
+ logger.debug("Memcached get_multi: #{keys.inspect}") if logger && @debug
150
+ values = super(keys, true)
151
+ logger.debug("Memcached hit: #{keys.inspect}") if logger && @debug
152
+ values
153
+ rescue Memcached::NotFound
154
+ logger.debug("Memcached miss: #{keys.inspect}") if logger && @debug
155
+ {}
142
156
  rescue TypeError
143
157
  log_error($!) if logger
144
158
  keys.each { |key| delete(key) }
@@ -150,7 +164,9 @@ class MemcachedWrapper < ::Memcached
150
164
  end
151
165
 
152
166
  def set(key, value, ttl=@default_ttl, raw=false)
167
+ logger.debug("Memcached set: #{key.inspect}") if logger && @debug
153
168
  super(key, value, ttl, !raw)
169
+ logger.debug("Memcached hit: #{key.inspect}") if logger && @debug
154
170
  stored
155
171
  rescue Memcached::Error
156
172
  log_error($!) if logger
@@ -158,27 +174,36 @@ class MemcachedWrapper < ::Memcached
158
174
  end
159
175
 
160
176
  def append(key, value)
177
+ logger.debug("Memcached append: #{key.inspect}") if logger && @debug
161
178
  super(key, value)
179
+ logger.debug("Memcached hit: #{key.inspect}") if logger && @debug
162
180
  stored
163
181
  rescue Memcached::NotStored
182
+ logger.debug("Memcached miss: #{key.inspect}") if logger && @debug
164
183
  not_stored
165
184
  rescue Memcached::Error
166
185
  log_error($!) if logger
167
186
  end
168
187
 
169
188
  def prepend(key, value)
189
+ logger.debug("Memcached prepend: #{key.inspect}") if logger && @debug
170
190
  super(key, value)
191
+ logger.debug("Memcached hit: #{key.inspect}") if logger && @debug
171
192
  stored
172
193
  rescue Memcached::NotStored
194
+ logger.debug("Memcached miss: #{key.inspect}") if logger && @debug
173
195
  not_stored
174
196
  rescue Memcached::Error
175
197
  log_error($!) if logger
176
198
  end
177
199
 
178
200
  def delete(key)
201
+ logger.debug("Memcached delete: #{key.inspect}") if logger && @debug
179
202
  super(key)
203
+ logger.debug("Memcached hit: #{key.inspect}") if logger && @debug
180
204
  deleted
181
205
  rescue Memcached::NotFound
206
+ logger.debug("Memcached miss: #{key.inspect}") if logger && @debug
182
207
  not_found
183
208
  rescue Memcached::Error
184
209
  log_error($!) if logger
@@ -198,6 +223,10 @@ class MemcachedWrapper < ::Memcached
198
223
  log_error($!) if logger
199
224
  end
200
225
 
226
+ def get_server_for_key(key, options = {})
227
+ server_by_key(key)
228
+ end
229
+
201
230
  alias :reset :quit
202
231
  alias :close :quit #nodoc
203
232
  alias :flush_all :flush
@@ -229,5 +258,5 @@ private
229
258
 
230
259
  end
231
260
  else
232
- Rails.logger.warn 'unable to determine memcache implementation'
261
+ Rails.logger.warn 'unable to determine memcache implementation' if defined? Rails
233
262
  end #include the wraper
@@ -30,6 +30,14 @@ module Cash
30
30
  end
31
31
  end
32
32
 
33
+ describe '#find(:first, :conditions => [ "id = :id", { :id => story.id } ])' do
34
+ it "does not use the database" do
35
+ story = Story.create!
36
+ mock(Story.connection).execute.never
37
+ Story.find(:first, :conditions => [ "id = :id", { :id => story.id } ]).should == story
38
+ end
39
+ end
40
+
33
41
  describe "#find(:first, :conditions => 'id = ?')" do
34
42
  it "does not use the database" do
35
43
  story = Story.create!
data/spec/spec_helper.rb CHANGED
@@ -6,7 +6,8 @@ require 'spec'
6
6
  require 'pp'
7
7
  require 'cache_money'
8
8
  #require 'memcache'
9
- #require 'memcached'
9
+ require 'memcached'
10
+ require 'memcached_wrapper'
10
11
 
11
12
  require File.join(dir, '../config/environment')
12
13
 
@@ -16,7 +17,7 @@ Spec::Runner.configure do |config|
16
17
  load File.join(dir, "../db/schema.rb")
17
18
 
18
19
  config = YAML.load(IO.read((File.expand_path(File.dirname(__FILE__) + "/../config/memcached.yml"))))['test']
19
- $memcache = MemcachedWrapper.new(config[:servers].gsub(' ', '').split(','), config)
20
+ $memcache = MemcachedWrapper.new(config["servers"].gsub(' ', '').split(','), config)
20
21
  $lock = Cash::Lock.new($memcache)
21
22
  end
22
23
 
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ngmoco-cache-money
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.2.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Kallen
8
+ - Ashley Martens
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
12
 
12
- date: 2009-10-26 00:00:00 -07:00
13
+ date: 2010-01-08 00:00:00 -08:00
13
14
  default_executable:
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency