Commit 0a656e72 authored by Adam Hegyi's avatar Adam Hegyi

Faster url generation

Modify ActionDispatch::Journey::Formatter#missing_keys method to prevent
rebuilding large regular expressions on each url generation call.
parent dddefcf5
---
title: Improve link generation performance
merge_request: 22426
author:
type: performance
# frozen_string_literal: true
# TODO: Eliminate this file when https://github.com/rails/rails/pull/38184 is released.
# Cleanup issue: https://gitlab.com/gitlab-org/gitlab/issues/195841
ActionDispatch::Journey::Formatter.prepend(Gitlab::Patch::ActionDispatchJourneyFormatter)
module ActionDispatch
module Journey
module Path
class Pattern
def requirements_for_missing_keys_check
@requirements_for_missing_keys_check ||= requirements.each_with_object({}) do |(key, regex), hash|
hash[key] = /\A#{regex}\Z/
end
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module Patch
module ActionDispatchJourneyFormatter
def self.prepended(mod)
mod.alias_method(:old_missing_keys, :missing_keys)
mod.remove_method(:missing_keys)
end
private
def missing_keys(route, parts)
missing_keys = nil
tests = route.path.requirements_for_missing_keys_check
route.required_parts.each do |key|
case tests[key]
when nil
unless parts[key]
missing_keys ||= []
missing_keys << key
end
else
unless tests[key].match?(parts[key])
missing_keys ||= []
missing_keys << key
end
end
end
missing_keys
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Patch::ActionDispatchJourneyFormatter do
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:url) { Gitlab::Routing.url_helpers.project_pipeline_url(project, pipeline) }
let(:expected_path) { "#{project.full_path}/pipelines/#{pipeline.id}" }
context 'custom implementation of #missing_keys' do
before do
expect_any_instance_of(Gitlab::Patch::ActionDispatchJourneyFormatter).to receive(:missing_keys)
end
it 'generates correct url' do
expect(url).to end_with(expected_path)
end
end
context 'original implementation of #missing_keys' do
before do
allow_any_instance_of(Gitlab::Patch::ActionDispatchJourneyFormatter).to receive(:missing_keys) do |instance, route, parts|
instance.send(:old_missing_keys, route, parts) # test the old implementation
end
end
it 'generates correct url' do
expect(url).to end_with(expected_path)
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