class Vash

Class: Vash (Ruby Volatile Hash) Hash that returns values only for a short time. This is useful as a cache where I/O is involved. The primary goal of this object is to reduce I/O access and due to the nature of I/O being slower then memory, you should also see a gain in quicker response times.

For example, if Person.first found the first person from the database & cache was an instance of Vash then the following would only contact the database for the first iteration:

> cache = Vash.new > 1000.times {cache ||= Person.first}

However if you did the following immediately following that command it would hit the database again:

> sleep 61 > cache ||= Person.first

The reason is that there is a default Time-To-Live of 60 seconds. You can also set a custom TTL of 10 seconds like so:

> cache[:person, 10] = Person.first

The Vash object will forget any answer that is requested after the specified TTL. It is a good idea to manually clean things up from time to time because it is possible that you'll cache data but never again access it and therefor it will stay in memory after the TTL has expired. To clean up the Vash object, call the method: cleanup!

> sleep 11 # At this point the prior person ttl will be expired

#  but the person key and value will still exist.

> cache # This will still show the the entire set of keys

#  regardless of the TTL, the :person will still exist

> cache.cleanup! # All of the TTL's will be inspected and the expired

#  :person key will be deleted.

The cleanup must be manually called because the purpose of the Vash is to lessen needless I/O calls and gain speed not to slow it down with regular maintenance.

Public Class Methods

new(constructor = {}) click to toggle source
Calls superclass method
# File lib/vash.rb, line 43
def initialize(constructor = {})
  @register ||= {} # remembers expiration time of every key
  if constructor.is_a?(Hash)
    super()
    merge(constructor)
  else
    super(constructor)
  end
end

Public Instance Methods

[](key) click to toggle source
# File lib/vash.rb, line 56
def [](key)
  sterilize(key)
  clear(key) if expired?(key)
  regular_reader(key)
end
Also aliased as: regular_reader
[]=(key, *args) click to toggle source
# File lib/vash.rb, line 62
def []=(key, *args)
  # a little bit o variable hacking to support (h[key, ttl] = value), which will come
  # accross as (key, [ttl, value]) whereas (h[key]=value) comes accross as (key, [value])
  if args.length == 2
    value, ttl = args[1], args[0]
  elsif args.length == 1
    value, ttl = args[0], 60
  else
    raise ArgumentError, "Wrong number of arguments, expected 2 or 3, received: #{args.length+1}\n"+
                         "Example Usage:  volatile_hash[:key]=value OR volatile_hash[:key, ttl]=value"
  end
  sterilize(key)
  ttl(key, ttl)
  regular_writer(key, value)
end
Also aliased as: regular_writer
cleanup!() click to toggle source
# File lib/vash.rb, line 83
def cleanup!
  now = Time.now.to_i
  @register.map {|k,v| clear(k) if v < now}
end
clear(key) click to toggle source
# File lib/vash.rb, line 88
def clear(key)
  sterilize(key)
  @register.delete key
  self.delete key
end
merge(hsh) click to toggle source
# File lib/vash.rb, line 78
def merge(hsh)
  hsh.map {|key,value| self[sterile(key)] = hsh[key]}
  self
end
regular_reader(key)
Alias for: []
regular_writer(key, *args)
Alias for: []=

Private Instance Methods

expired?(key) click to toggle source
# File lib/vash.rb, line 95
def expired?(key)
  Time.now.to_i > @register[key].to_i
end
sterile(key) click to toggle source
# File lib/vash.rb, line 103
def sterile(key)
  String === key ? key.chomp('!').chomp('=') : key.to_s.chomp('!').chomp('=').to_sym
end
sterilize(key) click to toggle source
# File lib/vash.rb, line 107
def sterilize(key)
  key = sterile(key)
end
ttl(key, secs=60) click to toggle source
# File lib/vash.rb, line 99
def ttl(key, secs=60)
  @register[key] = Time.now.to_i + secs.to_i
end