lib/ttl_memoizeable.rb in ttl_memoizeable-0.2.0 vs lib/ttl_memoizeable.rb in ttl_memoizeable-0.2.1
- old
+ new
@@ -5,27 +5,28 @@
require_relative "ttl_memoizeable/version"
module TTLMemoizeable
TTLMemoizationError = Class.new(StandardError)
+ SetupMutex = Mutex.new
def ttl_memoized_method(method_name, ttl: 1000)
raise TTLMemoizationError, "Method not defined: #{method_name}" unless method_defined?(method_name) || private_method_defined?(method_name)
ivar_name = method_name.to_s.gsub(/\??/, "") # remove trailing question marks
time_based_ttl = ttl.is_a?(ActiveSupport::Duration)
expired_ttl = time_based_ttl ? 1.year.ago : 1
- ttl_variable_name = "@_ttl_for_#{ivar_name}".to_sym
- mutex_variable_name = "@_mutex_for_#{ivar_name}".to_sym
- value_variable_name = "@_value_for_#{ivar_name}".to_sym
+ ttl_variable_name = :"@_ttl_for_#{ivar_name}"
+ mutex_variable_name = :"@_mutex_for_#{ivar_name}"
+ value_variable_name = :"@_value_for_#{ivar_name}"
- reset_memoized_value_method_name = "reset_memoized_value_for_#{method_name}".to_sym
- setup_memoization_method_name = "_setup_memoization_for_#{method_name}".to_sym
- decrement_ttl_method_name = "_decrement_ttl_for_#{method_name}".to_sym
- ttl_exceeded_method_name = "_ttl_exceeded_for_#{method_name}".to_sym
- extend_ttl_method_name = "_extend_ttl_for_#{method_name}".to_sym
+ reset_memoized_value_method_name = :"reset_memoized_value_for_#{method_name}"
+ setup_memoization_method_name = :"_setup_memoization_for_#{method_name}"
+ decrement_ttl_method_name = :"_decrement_ttl_for_#{method_name}"
+ ttl_exceeded_method_name = :"_ttl_exceeded_for_#{method_name}"
+ extend_ttl_method_name = :"_extend_ttl_for_#{method_name}"
[
reset_memoized_value_method_name, setup_memoization_method_name,
decrement_ttl_method_name, ttl_exceeded_method_name, extend_ttl_method_name
].each do |potential_method_name|
@@ -42,26 +43,28 @@
nil
end
define_method setup_memoization_method_name do
- instance_variable_set(ttl_variable_name, expired_ttl) unless instance_variable_defined?(ttl_variable_name)
- instance_variable_set(mutex_variable_name, Mutex.new) unless instance_variable_defined?(mutex_variable_name)
- instance_variable_set(value_variable_name, nil) unless instance_variable_defined?(value_variable_name)
+ return if instance_variable_defined?(ttl_variable_name) && instance_variable_defined?(mutex_variable_name)
+
+ ::TTLMemoizeable::SetupMutex.synchronize do
+ instance_variable_set(ttl_variable_name, expired_ttl) unless instance_variable_defined?(ttl_variable_name)
+ instance_variable_set(mutex_variable_name, Mutex.new) unless instance_variable_defined?(mutex_variable_name)
+ end
end
define_method decrement_ttl_method_name do
return if time_based_ttl
instance_variable_set(ttl_variable_name, instance_variable_get(ttl_variable_name) - 1)
end
define_method ttl_exceeded_method_name do
- instance_variable_get(ttl_variable_name) <= if time_based_ttl
- ttl.ago
- else
- 0
- end
+ return true unless instance_variable_defined?(value_variable_name)
+
+ compared_to = time_based_ttl ? ttl.ago : 0
+ instance_variable_get(ttl_variable_name) <= compared_to
end
define_method extend_ttl_method_name do
if time_based_ttl
instance_variable_set(ttl_variable_name, Time.current)