Skip to content

Instantly share code, notes, and snippets.

@alainravet
Last active December 17, 2015 09:59
Show Gist options
  • Select an option

  • Save alainravet/5591819 to your computer and use it in GitHub Desktop.

Select an option

Save alainravet/5591819 to your computer and use it in GitHub Desktop.
async preloading cache with code rewriting
# Ad-hoc code (no library)
#
module GemUtils
def self.gem_names # version 1 : 1st call
GEM_NAMES_PRELOADER.join.value # **1 : wait and return this if the cache is not ready
end
private
GEM_NAMES_PRELOADER = Thread.new do
@@_cached_gem_names = `gem list --no-version` # version 1 : slow
def GemUtils.gem_names # version 2 : fast
@@_cached_gem_names # **2
end #
@@_cached_gem_names # for **1
end
end
############
# Usage example :
############
3.times do
start = Time.now
puts GemUtils.gem_names.size.to_s + " " + (Time.now - start).to_s
end
# 204 3.858853
# 204 6.0e-06
# 204 4.0e-06
# extracted from code above : cattr_reader_preloaded
#
module Kernel
# Usage :
# cattr_reader_preloaded :gem_names do
# `gem list --no-version`
# end
#
def cattr_reader_preloaded(name, &block)
raise "initialization block is missing" unless block_given?
cache = "@_cached_#{name}" .to_sym
preloader = "@_#{name}_preloader".to_sym
self.class.send :define_method, name, -> {
instance_variable_get(preloader).join.value
}
instance_variable_set(preloader, Thread.new do
instance_variable_set cache, block.call
self.class.send :define_method, name, -> {
instance_variable_get cache
}
instance_variable_get cache
end)
end
end
end
############
# Usage example :
############
module GemUtils
cattr_reader_preloaded :gem_names do
`gem list --no-version`
end
end
3.times do
start = Time.now
puts GemUtils.gem_names.size.to_s + " " + (Time.now - start).to_s
end
# 204 3.858853
# 204 6.0e-06
# 204 4.0e-06
module GemUtils
cattr_reader_preloaded :slow do sleep 1 ; "AAAA" end
cattr_reader_preloaded :slow_2 do sleep 1 ; "BBBB" end
end
3.times { start = Time.now; puts GemUtils.slow + " " + (Time.now - start).to_s }
3.times { start = Time.now; puts GemUtils.slow_2 + " " + (Time.now - start).to_s }
# AAAA 1.001
# AAAA 5.0e-06
# AAAA 4.0e-06
# BBBB 5.0e-06
# BBBB 4.0e-06
# BBBB 4.0e-06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment