ngmoco-cache-money 0.2.9 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
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