Skip to content

Instantly share code, notes, and snippets.

@ab5tract
Created September 17, 2008 05:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ab5tract/11199 to your computer and use it in GitHub Desktop.
Save ab5tract/11199 to your computer and use it in GitHub Desktop.
module Waves
module Layers
module Cache
module FileCache
def self.included(app)
require 'layers/cache/filecache/filecache-ipi'
if Waves.cache.nil?
Waves.cache = Waves::Layers::Cache::FileCache::FileCacheIPI.new( Waves.config.cache )
end
end
end
end
end
end
module Waves
module Layers
module Cache
module FileCache
class FileCacheIPI < Waves::Cache
# IPI stands for 'Implemented Programming Interface'
def initialize(arg)
@directory = arg[:dir]
@cache = {}
rescue
raise ArgumentError, ":dir needs to not be nil" if arg[:dir].nil?
end
def store(key, value, ttl = {})
Waves.synchronize do
super(key, value, ttl)
@keys << key
key_file = @directory / key
file = File.new(key_file,'w')
Marshal.dump(@cache[key], file)
file.close
@cache.delete key
end
end
def delete(*keys)
Waves.synchronize do
keys.each do |key|
if @keys.include? key
File.delete(@directory / key)
@keys.delete key
else
raise KeyMissing, "no key #{key} to delete"
end
end
end
end
def clear
Waves.synchronize do
@keys.each {|key| File.delete(@directory / key) }
@keys.clear
end
end
def fetch(key)
Waves.synchronize do
raise KeyMissing, "#{key} doesn't exist" unless File.exists?(@directory / key)
@cache[key] = Marshal.load File.new(@directory / key)
return @cache[key][:value] if @cache[key][:expires].nil?
if @cache[key][:expires] > Time.now
@cache[key][:value]
else
delete key
raise KeyMissing, "#{key} expired before access attempt"
end
end
end
end
end
end
end
end
#!waves#########/0.8.0/##\|/4V35###
# a Waves Cache brought to you by ab5tract
# :This is the Cache API. Do as you will, so long as you return what I do.
###################################
module Waves
class Cache
# Exception classes
class KeyMissing < StandardError; end
def initialize
#Waves.synchronize { @cache = {} }
@cache = {} #raise TriedBoth
end
# Universal to all cache objects.
def [](key)
fetch(key)
end
def []=(key,value)
store(key,value )
end
def exists?(key)
fetch(key)
rescue KeyMissing
return false
else
return true
end
alias_method :exist?, :exists?
# Replicate the same capabilities in any descendent of Waves::Cache for API compatibility.
def store(key, value, ttl = {})
Waves.synchronize do
@cache[key] = {
:expires => ttl.kind_of?(Numeric) ? Time.now + ttl : nil,
:value => value
}
end
end
def delete(*keys)
Waves.synchronize { keys.each {|key| @cache.delete(key) }}
end
def clear
Waves.synchronize { @cache.clear }
end
def fetch(key)
Waves.synchronize do
raise KeyMissing, "#{key} doesn't exist in cache" if @cache.has_key?(key) == false
return @cache[key][:value] if @cache[key][:expires].nil?
if @cache[key][:expires] > Time.now
@cache[key][:value]
else
delete key
raise KeyMissing, "#{key} expired before access attempt"
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment