Commit f2fa7c10 authored by Michael Kozono's avatar Michael Kozono

Remove send-in-send for safety and readability

I attempted to refactor so that the caller of `wrap_method` passes in a
block, rather than a method name, but I was unsuccessful.

I kept getting the following error:

NoMethodError:
        undefined method `cache_method_output' for Repository:Class

If you can figure this out, then feel free to dry up these class methods
again without doing a send-within-a-send.
parent f807ea33
...@@ -12,7 +12,13 @@ module Gitlab ...@@ -12,7 +12,13 @@ module Gitlab
# fallback - A value to fall back to if the repository does not exist, or # fallback - A value to fall back to if the repository does not exist, or
# in case of a Git error. Defaults to nil. # in case of a Git error. Defaults to nil.
def cache_method(name, fallback: nil) def cache_method(name, fallback: nil)
wrap_method(name, :cache_method_output, fallback: fallback) uncached_name = alias_uncached_method(name)
define_method(name) do
cache_method_output(name, fallback: fallback) do
__send__(uncached_name) # rubocop:disable GitlabSecurity/PublicSend
end
end
end end
# Caches truthy values from the method. All values are strongly memoized, # Caches truthy values from the method. All values are strongly memoized,
...@@ -26,7 +32,13 @@ module Gitlab ...@@ -26,7 +32,13 @@ module Gitlab
# #
# name - The name of the method to be cached. # name - The name of the method to be cached.
def cache_method_asymmetrically(name) def cache_method_asymmetrically(name)
wrap_method(name, :cache_method_output_asymmetrically) uncached_name = alias_uncached_method(name)
define_method(name) do
cache_method_output_asymmetrically(name) do
__send__(uncached_name) # rubocop:disable GitlabSecurity/PublicSend
end
end
end end
# Strongly memoizes the method. # Strongly memoizes the method.
...@@ -38,22 +50,25 @@ module Gitlab ...@@ -38,22 +50,25 @@ module Gitlab
# in case of a Git error. Defaults to nil. The fallback value # in case of a Git error. Defaults to nil. The fallback value
# is not memoized. # is not memoized.
def memoize_method(name, fallback: nil) def memoize_method(name, fallback: nil)
wrap_method(name, :memoize_method_output, fallback: fallback) uncached_name = alias_uncached_method(name)
end
# Prepends "_uncached_" to the target method name, and redefines the method
# but wraps it in the `wrapper` method.
def wrap_method(name, wrapper, *options)
original = :"_uncached_#{name}"
alias_method(original, name)
define_method(name) do define_method(name) do
__send__(wrapper, name, *options) do # rubocop:disable GitlabSecurity/PublicSend memoize_method_output(name, fallback: fallback) do
__send__(original) # rubocop:disable GitlabSecurity/PublicSend __send__(uncached_name) # rubocop:disable GitlabSecurity/PublicSend
end end
end end
end end
# Prepends "_uncached_" to the target method name
#
# Returns the uncached method name
def alias_uncached_method(name)
uncached_name = :"_uncached_#{name}"
alias_method(uncached_name, name)
uncached_name
end
end end
# RequestStore-backed RepositoryCache to be used. Should be overridden by # RequestStore-backed RepositoryCache to be used. Should be overridden by
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment