Sha256: 122a5c3856f77ccddd19daecd5f2f45bcbdf2679ed5449cbb290b0cdfb44b6f1
Contents?: true
Size: 1.36 KB
Versions: 2
Compression:
Stored size: 1.36 KB
Contents
require "expiring_memoize/version" module ExpiringMemoize # Memoize a nullary method. # @param name [Symbol] method to memoize # @option ttl [Number] time to live of the value, in seconds def memoize name, ttl: Float::INFINITY original = instance_method name raise ArgumentError, 'only nullary methods supported' unless original.arity.zero? define_method name do data = ((@_expiring_memoize_data ||= {})[name] ||= {}) loop do # no need to synchronize here -- worst case, # we return a value fresher than expected. # (plus, global interpreter lock in MRI makes it safe regardless) unless (ts = data[:timestamp]) && (ExpiringMemoize.gettime - ts) < ttl # value is stale, race to fetch mutex ||= (data[:mutex] ||= Mutex.new) if mutex.try_lock # our thread won the race, let's get the value begin data[:value] = original.bind(self).call data[:timestamp] = ExpiringMemoize.gettime ensure mutex.unlock end else # our thread lost, block on the mutex and try again mutex.synchronize {} next end end return data[:value] end end end # @nodoc def self.gettime Process.clock_gettime Process::CLOCK_MONOTONIC_COARSE end end
Version data entries
2 entries across 2 versions & 1 rubygems
Version | Path |
---|---|
expiring_memoize-0.1.1 | lib/expiring_memoize.rb |
expiring_memoize-0.1.0 | lib/expiring_memoize.rb |