Class: MethodCache::Proxy

Inherits:
Object show all
Defined in:
lib/method_cache/proxy.rb

Constant Summary collapse

NULL =
'NULL'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(method_name, opts) ⇒ Proxy

Returns a new instance of Proxy.



12
13
14
15
16
# File 'lib/method_cache/proxy.rb', line 12

def initialize(method_name, opts)
  opts[:cache] ||= :counters if opts[:counter]
  @method_name = method_name
  @opts        = opts
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



9
10
11
# File 'lib/method_cache/proxy.rb', line 9

def args
  @args
end

#method_nameObject (readonly)

Returns the value of attribute method_name.



9
10
11
# File 'lib/method_cache/proxy.rb', line 9

def method_name
  @method_name
end

#optsObject (readonly)

Returns the value of attribute opts.



9
10
11
# File 'lib/method_cache/proxy.rb', line 9

def opts
  @opts
end

#targetObject (readonly)

Returns the value of attribute target.



9
10
11
# File 'lib/method_cache/proxy.rb', line 9

def target
  @target
end

Instance Method Details

#bind(target, args) ⇒ Object



18
19
20
# File 'lib/method_cache/proxy.rb', line 18

def bind(target, args)
  self.clone.bind!(target, args)
end

#bind!(target, args) ⇒ Object



22
23
24
25
26
27
# File 'lib/method_cache/proxy.rb', line 22

def bind!(target, args)
  @target = target
  @args   = args
  @key    = nil
  self
end

#cacheObject



115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/method_cache/proxy.rb', line 115

def cache
  if @cache.nil?
    @cache = opts[:cache] || MethodCache.default_cache
    @cache = Memcache.pool[@cache] if @cache.kind_of?(Symbol)
    if not @cache.respond_to?(:[]) and @cache.respond_to?(:get)
      @cache.metaclass.module_eval do
        define_method :[] do |key|
          get(key)
        end
      end
    end
  end
  @cache
end

#cached?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/method_cache/proxy.rb', line 46

def cached?
  not cache[key].nil?
end

#cached_atObject



149
150
151
# File 'lib/method_cache/proxy.rb', line 149

def cached_at
  cache.cached_at(key) if cache.respond_to?(:cached_at)
end

#clone?Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/method_cache/proxy.rb', line 134

def clone?
  !!opts[:clone]
end

#contextObject



38
39
40
# File 'lib/method_cache/proxy.rb', line 38

def context
  opts[:context]
end

#counter_method(method_name) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/method_cache/proxy.rb', line 96

def counter_method(method_name)
  proxy = self # Need access to the proxy in the closure.

  lambda do |*args|
    if args.last.kind_of?(Hash) and args.last.keys == [:by]
      amount = args.last[:by]
      args.pop
    end
    proxy.bind(self, args).send(method_name, amount || 1)
  end
end

#expires_atObject



153
154
155
# File 'lib/method_cache/proxy.rb', line 153

def expires_at
  cache.expires_at(key) if cache.respond_to?(:expires_at)
end

#invalidateObject



29
30
31
32
33
34
35
36
# File 'lib/method_cache/proxy.rb', line 29

def invalidate
  if block_given?
    # Only invalidate if the block returns true.
    value = cache[key]
    return if value and not yield(value)
  end
  cache.delete(key)
end

#keyObject



138
139
140
141
142
143
144
145
146
147
# File 'lib/method_cache/proxy.rb', line 138

def key
  if @key.nil?
    arg_string = ([method_name, target] + args).collect do |arg|
      object_key(arg)
    end.join('|')
    @key = [version, arg_string].compact.join('|')
    @key = Digest::SHA1.hexdigest(@key) if @key.length > 250
  end
  "m#{MethodCache.version}|#{@key}"
end

#local?Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/method_cache/proxy.rb', line 130

def local?
  cache.kind_of?(LocalCache) or cache.kind_of?(Hash)
end

#method_name_without_cachingObject



108
109
110
111
112
113
# File 'lib/method_cache/proxy.rb', line 108

def method_name_without_caching
  @method_name_without_caching ||= begin
    base_name, punctuation = method_name.to_s.sub(/([?!=])$/, ''), $1
    "#{base_name}_without_caching#{punctuation}".to_sym
  end
end

#method_with_cachingObject



88
89
90
91
92
93
94
# File 'lib/method_cache/proxy.rb', line 88

def method_with_caching
  proxy = self # Need access to the proxy in the closure.

  lambda do |*args|
    proxy.bind(self, args).value
  end
end

#updateObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/method_cache/proxy.rb', line 50

def update
  if block_given?
    old_value = read_from_cache(key)
    return if old_value.nil?

    old_value = nil if old_value == NULL
    new_value = yield(old_value)
    return if old_value == new_value
  else
    new_value = target.send(method_name_without_caching, *args)
  end
  write_to_cache(key, new_value)
  new_value
end

#valueObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/method_cache/proxy.rb', line 65

def value
  value = read_from_cache(key)
  value = nil unless valid?(:load, value)

  if value.nil?
    value = target.send(method_name_without_caching, *args)
    raise "non-integer value returned by counter method" if opts[:counter] and not value.kind_of?(Fixnum)
    write_to_cache(key, value) if valid?(:save, value)
  end

  if opts[:counter]
    value = [value, opts[:max]].min if opts[:max]
    value = [value, opts[:min]].max if opts[:min]
  end

  value = nil if value == NULL
  if clone? and value
    value.clone
  else
    value
  end
end

#versionObject



42
43
44
# File 'lib/method_cache/proxy.rb', line 42

def version
  dynamic_opt(:version)
end