Skip to content

Instantly share code, notes, and snippets.

@machu
Created July 1, 2010 16:01
Show Gist options
  • Save machu/460157 to your computer and use it in GitHub Desktop.
Save machu/460157 to your computer and use it in GitHub Desktop.
# = CachedPStore -- PStore extension w/ cache mechanism
#
# Copyright (C) 2010, MATSUOKA Kohei
# You can redistribute it and/or modify it under GPL2.
#
# == Usage examle:
#
# require 'cached_pstore'
#
# db = CachedPStore.new('test.dat', :expire => 3600) {|db, key|
# # update_proc
# db[key] = 'update value'
# }
# db.transaction {|db|
# db[:key1] = 'value1'
# puts db[:key1] # => 'value1'
# }
#
# ### Some time later... ###
#
# db.transaction {|db|
# # value is expired, it calls update_proc
# puts db[:key] # => 'update value'
# }
#
require 'pstore'
class CachedPStore < PStore
def initialize(filename, options = {}, &update_proc)
@timeout = options[:timeout] || 60 * 60
@version = options[:version] || 1
@update_proc = update_proc
super(filename)
end
def [](name)
value = super(name) || {}
expired = (value[:updated_at] == nil ||
value[:updated_at] + @timeout < Time.now ||
value[:version] < @version)
if expired && @update_proc
self[name] = @update_proc.call(name)
else
value[:entity]
end
end
def []=(name, value)
super(name, {
:version => @version,
:updated_at => Time.now,
:entity => value
})
end
end
# -*- coding: utf-8 -*-
#
require 'cached_pstore'
require 'fileutils'
describe CachedPStore do
before(:each) do
File.unlink('test.dat') if File.exist?('test.dat')
end
it "初期化されていないキーを読み込むと、更新ブロックで初期化されること" do
CachedPStore.new('test.dat') {|db, key|
'default'
}.transaction {|db|
db[:uninitialized].should == 'default'
}
end
it "有効期限が切れると更新ブロックで更新されること" do
db = CachedPStore.new('test.dat', :timeout => 1) {|db, key|
'default'
}
db.transaction {|db|
db[:initialized] = 'initialized'
db[:initialized].should == 'initialized'
}
sleep 1
db.transaction {|db|
db[:initialized].should == 'default'
}
end
it "初期化ブロックが渡されない場合は有効期限が切れても更新されない" do
db = CachedPStore.new('test.dat', :timeout => 1)
db.transaction {|db|
db[:initialized] = 'initialized'
db[:initialized].should == 'initialized'
}
sleep 1
db.transaction {|db|
db[:initialized].should == 'initialized'
}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment