Class: SynCache::Cache

Inherits:
Object
  • Object
show all
Defined in:
lib/syncache/syncache.rb

Constant Summary collapse

LOCK_SLEEP =

a float number of seconds to sleep when a race condition is detected (actual delay is randomized to avoid live lock situation)

0.2

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ttl = 60*60, max_size = 5000, flush_delay = nil) ⇒ Cache

ttl (time to live) is time in seconds from the last access until cache entry is expired (set to nil to disable time limit)

max_size is max number of objects in cache

flush_delay is used to rate-limit flush operations: if less than that number of seconds has passed since last flush, next flush will be delayed; default is no rate limit



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/syncache/syncache.rb', line 80

def initialize(ttl = 60*60, max_size = 5000, flush_delay = nil)
  @ttl = ttl
  @max_size = max_size
  @debug = false

  if @flush_delay = flush_delay
    @last_flush = Time.now
  end

  @sync = Mutex.new
  @cache = {}
end

Instance Attribute Details

#debug=(value) ⇒ Object

set to true to report every single cache operation



95
96
97
# File 'lib/syncache/syncache.rb', line 95

def debug=(value)
  @debug = value
end

Instance Method Details

#[](key) ⇒ Object

retrieve value from cache if it’s still fresh

see also Cache#fetch_or_add



152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/syncache/syncache.rb', line 152

def [](key)
  debug { '[] ' << key.to_s }

  entry = get_locked_entry(key, false)
  unless entry.nil?
    begin
      return entry.value
    ensure
      entry.sync.unlock
    end
  end
end

#[]=(key, value) ⇒ Object

store new value in cache

see also Cache#fetch_or_add



137
138
139
140
141
142
143
144
145
146
# File 'lib/syncache/syncache.rb', line 137

def []=(key, value)
  debug { '[]= ' << key.to_s }

  entry = get_locked_entry(key)
  begin
    return entry.value = value
  ensure
    entry.sync.unlock
  end
end

#delete(key) ⇒ Object

remove single value from cache



125
126
127
128
129
130
131
# File 'lib/syncache/syncache.rb', line 125

def delete(key)
  debug { 'delete ' << key.to_s }

  @sync.synchronize do
    @cache.delete(key)
  end
end

#fetch_or_add(key) ⇒ Object

initialize missing cache entry from supplied block

this is the preferred method of adding values to the cache as it locks the key for the duration of computation of the supplied block to prevent parallel execution of resource-intensive actions



171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/syncache/syncache.rb', line 171

def fetch_or_add(key)
  debug { 'fetch_or_add ' << key.to_s }

  entry = get_locked_entry(key)
  begin
    if entry.value.nil?
      entry.value = yield
    end
    return entry.value
  ensure
    entry.sync.unlock
  end
end

#flush(base = nil) ⇒ Object

remove all values from cache

if base is given, only values with keys matching the base (using === operator) are removed



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/syncache/syncache.rb', line 102

def flush(base = nil)
  debug { 'flush ' << base.to_s }

  @sync.synchronize do

    if @flush_delay
      next_flush = @last_flush + @flush_delay

      if next_flush > Time.now
        flush_at(next_flush, base)
      else
        flush_now(base)
        @last_flush = Time.now
      end

    else
      flush_now(base)
    end
  end
end