Commit 1c116bc9 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch '39842-fetch-ivar' into 'master'

Add Gitlab::Utils::StrongMemoize

Allows patterns like this:

    def trigger_from_token
      return @Trigger if defined?(@Trigger)

      @Trigger = Ci::Trigger.find_by_token(params[:token].to_s)
    end

Closes #39842

See merge request gitlab-org/gitlab-ce!15222
parents 4a1e8188 258bf3e1
module Ci
class PipelineTriggerService < BaseService
include Gitlab::Utils::StrongMemoize
def execute
if trigger_from_token
create_pipeline_from_trigger(trigger_from_token)
......@@ -26,9 +28,9 @@ module Ci
end
def trigger_from_token
return @trigger if defined?(@trigger)
@trigger = Ci::Trigger.find_by_token(params[:token].to_s)
strong_memoize(:trigger) do
Ci::Trigger.find_by_token(params[:token].to_s)
end
end
def create_pipeline_variables!(pipeline)
......
......@@ -42,6 +42,8 @@ module API
# Helper Methods for Grape Endpoint
module HelperMethods
include Gitlab::Utils::StrongMemoize
def find_current_user!
user = find_user_from_access_token || find_user_from_warden
return unless user
......@@ -52,9 +54,9 @@ module API
end
def access_token
return @access_token if defined?(@access_token)
@access_token = find_oauth_access_token || find_personal_access_token
strong_memoize(:access_token) do
find_oauth_access_token || find_personal_access_token
end
end
def validate_access_token!(scopes: [])
......
module Gitlab
module Utils
module StrongMemoize
# Instead of writing patterns like this:
#
# def trigger_from_token
# return @trigger if defined?(@trigger)
#
# @trigger = Ci::Trigger.find_by_token(params[:token].to_s)
# end
#
# We could write it like:
#
# def trigger_from_token
# strong_memoize(:trigger) do
# Ci::Trigger.find_by_token(params[:token].to_s)
# end
# end
#
def strong_memoize(name)
ivar_name = "@#{name}"
if instance_variable_defined?(ivar_name)
instance_variable_get(ivar_name)
else
instance_variable_set(ivar_name, yield)
end
end
end
end
end
require 'spec_helper'
describe Gitlab::Utils::StrongMemoize do
let(:klass) do
struct = Struct.new(:value) do
def method_name
strong_memoize(:method_name) do
trace << value
value
end
end
def trace
@trace ||= []
end
end
struct.include(described_class)
struct
end
subject(:object) { klass.new(value) }
shared_examples 'caching the value' do
it 'only calls the block once' do
value0 = object.method_name
value1 = object.method_name
expect(value0).to eq(value)
expect(value1).to eq(value)
expect(object.trace).to contain_exactly(value)
end
it 'returns and defines the instance variable for the exact value' do
returned_value = object.method_name
memoized_value = object.instance_variable_get(:@method_name)
expect(returned_value).to eql(value)
expect(memoized_value).to eql(value)
end
end
describe '#strong_memoize' do
[nil, false, true, 'value', 0, [0]].each do |value|
context "with value #{value}" do
let(:value) { value }
it_behaves_like 'caching the value'
end
end
end
end
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