diff options
author | Jan Provaznik <jprovaznik@gitlab.com> | 2019-08-30 14:36:52 +0300 |
---|---|---|
committer | Jan Provaznik <jprovaznik@gitlab.com> | 2019-08-30 14:36:52 +0300 |
commit | e668b1e2eae4b3d4bc00dc0b1571721f111b0b92 (patch) | |
tree | 24c898b466e8ed14ce37c3a479c2878be6f502eb /app/models | |
parent | 293b4797753fff18c4825fcfa6775b01f220da63 (diff) | |
parent | edde1b708a6a605185a6dde73550b9f45e673371 (diff) |
Merge branch 'ab-routable-two-step-search' into 'master'
Perform two-step Routable lookup by path
See merge request gitlab-org/gitlab-ce!32272
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/concerns/routable.rb | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index 116e8967651..3a486632800 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -33,8 +33,17 @@ module Routable # # Returns a single object, or nil. def find_by_full_path(path, follow_redirects: false) - order_sql = Arel.sql("(CASE WHEN routes.path = #{connection.quote(path)} THEN 0 ELSE 1 END)") - found = where_full_path_in([path]).reorder(order_sql).take + increment_counter(:routable_find_by_full_path, 'Number of calls to Routable.find_by_full_path') + + if Feature.enabled?(:routable_two_step_lookup) + # Case sensitive match first (it's cheaper and the usual case) + # If we didn't have an exact match, we perform a case insensitive search + found = joins(:route).find_by(routes: { path: path }) || where_full_path_in([path]).take + else + order_sql = Arel.sql("(CASE WHEN routes.path = #{connection.quote(path)} THEN 0 ELSE 1 END)") + found = where_full_path_in([path]).reorder(order_sql).take + end + return found if found if follow_redirects @@ -52,12 +61,23 @@ module Routable def where_full_path_in(paths) return none if paths.empty? + increment_counter(:routable_where_full_path_in, 'Number of calls to Routable.where_full_path_in') + wheres = paths.map do |path| "(LOWER(routes.path) = LOWER(#{connection.quote(path)}))" end joins(:route).where(wheres.join(' OR ')) end + + # Temporary instrumentation of method calls + def increment_counter(counter, description) + @counters[counter] ||= Gitlab::Metrics.counter(counter, description) + + @counters[counter].increment + rescue + # ignore the error + end end def full_name |