Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Expand cache keys like ActiveSupport::Cache
  • Loading branch information
twinturbo committed May 8, 2012
1 parent ee5193e commit 90c09c8
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 3 deletions.
46 changes: 43 additions & 3 deletions lib/active_support/cache/dalli_store.rb
Expand Up @@ -46,6 +46,8 @@ def initialize(*addresses)

def fetch(name, options=nil)
options ||= {}
name = namespaced_key(name, options)

if block_given?
unless options[:force]
entry = instrument(:read, name, options) do |payload|
Expand All @@ -71,6 +73,8 @@ def fetch(name, options=nil)

def read(name, options=nil)
options ||= {}
name = namespaced_key(name, options)

instrument(:read, name, options) do |payload|
entry = read_entry(name, options)
payload[:hit] = !!entry if payload
Expand All @@ -80,27 +84,33 @@ def read(name, options=nil)

def write(name, value, options=nil)
options ||= {}
name = namespaced_key(name, options)

instrument(:write, name, options) do |payload|
write_entry(name, value, options)
end
end

def exist?(name, options=nil)
options ||= {}
name = namespaced_key(name, options)

!read_entry(name, options).nil?
end

def delete(name, options=nil)
options ||= {}
name = namespaced_key(name, options)

delete_entry(name, options)
end

# Reads multiple keys from the cache using a single call to the
# servers for all keys. Keys must be Strings.
def read_multi(*names)
names.extract_options!
options = names.extract_options!
names = names.flatten

mapping = names.inject({}) { |memo, name| memo[escape(name)] = name; memo }
mapping = names.inject({}) { |memo, name| memo[escape(namespaced_key(name, options))] = name; memo }
instrument(:read_multi, names) do
results = @data.get_multi(mapping.keys)
results.inject({}) do |memo, (inner, value)|
Expand All @@ -119,6 +129,7 @@ def read_multi(*names)
# memcached counters cannot hold negative values.
def increment(name, amount = 1, options=nil)
options ||= {}
name = namespaced_key(name, options)
initial = options.has_key?(:initial) ? options[:initial] : amount
expires_in = options[:expires_in]
instrument(:increment, name, :amount => amount) do
Expand All @@ -137,6 +148,7 @@ def increment(name, amount = 1, options=nil)
# memcached counters cannot hold negative values.
def decrement(name, amount = 1, options=nil)
options ||= {}
name = namespaced_key(name, options)
initial = options.has_key?(:initial) ? options[:initial] : 0
expires_in = options[:expires_in]
instrument(:decrement, name, :amount => amount) do
Expand Down Expand Up @@ -197,6 +209,34 @@ def delete_entry(key, options) # :nodoc:
end

private
# Expand key to be a consistent string value. Invoke +cache_key+ if
# object responds to +cache_key+. Otherwise, to_param method will be
# called. If the key is a Hash, then keys will be sorted alphabetically.
def expanded_key(key) # :nodoc:
return key.cache_key.to_s if key.respond_to?(:cache_key)

case key
when Array
if key.size > 1
key = key.collect{|element| expanded_key(element)}
else
key = key.first
end
when Hash
key = key.sort_by { |k,_| k.to_s }.collect{|k,v| "#{k}=#{v}"}
end

key.to_param
end

# Prefix a key with the namespace. Namespace and key will be delimited with a colon.
def namespaced_key(key, options = {})
key = expanded_key(key)
namespace = options[:namespace] if options
prefix = namespace.is_a?(Proc) ? namespace.call : namespace
key = "#{prefix}:#{key}" if prefix
key
end

def escape(key)
key = key.to_s.dup
Expand Down
32 changes: 32 additions & 0 deletions test/test_active_support.rb
@@ -1,6 +1,12 @@
# encoding: utf-8
require 'helper'

class MockUser
def cache_key
"users/1/21348793847982314"
end
end

describe 'ActiveSupport' do
context 'active_support caching' do

Expand Down Expand Up @@ -50,6 +56,11 @@
@dalli.write('false', false)
dvalue = @dalli.fetch('false') { flunk }
assert_equal false, dvalue

user = MockUser.new
@dalli.write(user.cache_key, false)
dvalue = @dalli.fetch(user) { flunk }
assert_equal false, dvalue
end
end
end
Expand Down Expand Up @@ -118,6 +129,16 @@

dres = @dalli.delete(y)
assert_equal true, dres

user = MockUser.new
dres = @dalli.write(user.cache_key, "foo")
assert_equal true, dres

dres = @dalli.read(user)
assert_equal "foo", dres

dres = @dalli.delete(user)
assert_equal true, dres
end
end
end
Expand Down Expand Up @@ -149,6 +170,13 @@

assert_equal nil, @dalli.decrement('counterZ2', 1, :initial => nil)
assert_equal nil, @dalli.read('counterZ2')

user = MockUser.new
assert_equal true, @dalli.write(user, 0, :raw => true)
assert_equal 1, @dalli.increment(user)
assert_equal 2, @dalli.increment(user)
assert_equal 1, @dalli.decrement(user)
assert_equal "1", @dalli.read(user, :raw => true)
end
end
end
Expand All @@ -164,6 +192,10 @@
assert_equal true, @dalli.exist?(:false_value)

assert_equal false, @dalli.exist?(:bar)

user = MockUser.new
@dalli.write(user, 'foo')
assert_equal true, @dalli.exist?(user)
end
end
end
Expand Down

0 comments on commit 90c09c8

Please sign in to comment.