Class: BlockCache

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

Overview

This is a class used to cache data from the repository, so that it needn't be queried over and over. Use a timeout of a few seconds to prevent repeated queries in the same operation, but preserve the ability to retrieve up to date data.

You can call #refresh to reset all the timeouts manually if you need to guarantee fresh data

Example usage:

def cache

@cache ||= begin
  c = BlockCache.new
  c.add("test", 10) { "Hello world!" }
  # This block always returns the same thing, so never refresh it
  c.add("test2") { |name| "Hello #{name}" }
  c
end

end

cache[“test2”, “Matthew”] # “Hello Matthew”

Instance Method Summary collapse

Constructor Details

#initialize(default = nil) ⇒ BlockCache

attr_reader :values, :accessed


28
29
30
31
32
33
34
# File 'lib/blockcache.rb', line 28

def initialize(default=nil)
  @default_value = default
  @blocks = {}
  @timeouts = {}
  @accessed = {}
  @values = {}
end

Instance Method Details

#[](name, *args) ⇒ Object


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/blockcache.rb', line 41

def [](name, *args)
  return @default_value if not @blocks.keys.include?(name)
  
  atime = get_accessed(@accessed, [name, *args])
  ctime = Time.now
  
  if ((not @timeouts[name].nil?) or (not value_exist?(@values, [name, *args]))) and ctime - atime > (@timeouts[name] || 0)
    begin
      set_value(@values, @blocks[name].call(*args), [name, *args])
    rescue
      # dump errors to the console, but otherwise, keep on trucking
      puts $!.message
      puts $!.backtrace
      set_value(@values, @default_value, [name, *args])
    end
    
    set_accessed(@accessed, ctime, [name, *args])
  end
  
  get_value(@values, [name, *args])
end

#add(name, timeout, &block) ⇒ Object


36
37
38
39
# File 'lib/blockcache.rb', line 36

def add(name, timeout, &block)
  @blocks[name] = block
  @timeouts[name] = timeout
end

#refresh(times = @accessed) ⇒ Object


63
64
65
66
67
68
69
70
71
# File 'lib/blockcache.rb', line 63

def refresh(times=@accessed)
  times.each do |k, v|
    if v.respond_to? '[]'
      refresh v
    else
      times[k] = Time.at(0)
    end
  end
end