Skip to content

Commit 0eabea6

Browse files
committed
Optimizations
1 parent 3368c50 commit 0eabea6

File tree

7 files changed

+44
-22
lines changed

7 files changed

+44
-22
lines changed

app/controllers/gems_controller.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ class GemsController < ApplicationController
66

77
prepend_before_action do
88
@title = "RubyGems"
9-
@collection = Library.allowed_gem.all
9+
# Select only needed columns to reduce memory usage
10+
@collection = Library.allowed_gem.select(:id, :name, :source, :owner, :versions)
1011
end
1112

1213
def index

app/controllers/github_controller.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ class GithubController < ApplicationController
88

99
prepend_before_action do
1010
@title = "GitHub Projects"
11-
@collection = Library.allowed_github.all
11+
# Select only needed columns to reduce memory usage
12+
@collection = Library.allowed_github.select(:id, :name, :source, :owner, :versions, :updated_at)
1213
end
1314

1415
def index

app/helpers/application_helper.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,16 @@ def has_featured?
8181
end
8282

8383
def featured_libraries
84-
Rubydoc.config.libraries[:featured].map do |name, source|
84+
featured_config = Rubydoc.config.libraries[:featured]
85+
return [] if featured_config.blank?
86+
87+
# Batch load all gem libraries in one query to avoid N+1
88+
gem_names = featured_config.select { |_, source| source == "gem" }.keys
89+
gem_libraries = Library.gem.where(name: gem_names).index_by(&:name)
90+
91+
featured_config.map do |name, source|
8592
if source == "gem"
86-
Library.gem.find_by(name: name)
93+
gem_libraries[name]
8794
elsif source == "featured"
8895
versions = FeaturedLibrary.versions_for(name)
8996
Library.new(name: name, source: :featured, versions: versions)

app/jobs/update_remote_gems_list_job.rb

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,21 @@ def perform
2323
logger.info "Updating remote RubyGems..."
2424

2525
inserts = []
26-
changed_gems = Library.gem.all.map { |lib| [ lib.name, lib ] }.to_h
27-
removed_gems = changed_gems.keys
26+
# Use pluck + index to reduce memory usage instead of loading full AR objects
27+
changed_gems = Library.gem.pluck(:name, :id, :versions).each_with_object({}) do |(name, id, versions), hash|
28+
hash[name] = { id: id, versions: versions }
29+
end
30+
removed_gems = changed_gems.keys.to_set
2831

2932
fetch_remote_gems.each do |name, versions|
3033
versions = pick_best_versions(versions)
31-
lib = changed_gems[name]
34+
lib_data = changed_gems[name]
3235

33-
if lib
36+
if lib_data
3437
removed_gems.delete(name)
3538

36-
if lib.versions != versions
37-
lib.update(versions: versions)
39+
if lib_data[:versions] != versions
40+
Library.where(id: lib_data[:id]).update_all(versions: versions)
3841
else
3942
changed_gems.delete(name)
4043
end
@@ -53,8 +56,8 @@ def perform
5356
end
5457

5558
if removed_gems.size > 0
56-
Library.delete_by(name: removed_gems)
57-
logger.info "Removed #{removed_gems.size} gems: #{removed_gems.join(', ')}"
59+
Library.where(source: :remote_gem, name: removed_gems.to_a).delete_all
60+
logger.info "Removed #{removed_gems.size} gems: #{removed_gems.to_a.join(', ')}"
5861
end
5962
ensure
6063
self.class.clear_lock_file if @can_clear_lock_file
@@ -96,8 +99,9 @@ def flush_cache(gem_names)
9699
end
97100
CacheClearJob.perform_later("/gems", "/featured", *index_map.keys.map { |k| "/gems/~#{k}" })
98101

99-
gem_names.each_slice(50) do |list|
100-
CacheClearJob.perform_later(*list.map { |k| [ "/gems/#{k}/", "/list/gems/#{k}/", "/static/gems/#{k}" ] }.flatten)
102+
# Batch into larger chunks to reduce job overhead
103+
gem_names.each_slice(100) do |list|
104+
CacheClearJob.perform_later(*list.flat_map { |k| [ "/gems/#{k}/", "/list/gems/#{k}/", "/static/gems/#{k}" ] })
101105
end
102106
end
103107
end

app/models/library.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@ def self.wildcard(list)
2020
end
2121

2222
def library_versions
23-
items = versions.map do |v|
24-
ver, platform = *v.split(",")
25-
lib = YARD::Server::LibraryVersion.new(name, ver, nil, source)
26-
lib.platform = platform
27-
lib
28-
end
23+
@library_versions ||= begin
24+
items = versions.map do |v|
25+
ver, platform = *v.split(",")
26+
lib = YARD::Server::LibraryVersion.new(name, ver, nil, source)
27+
lib.platform = platform
28+
lib
29+
end
2930

30-
source == :github ? sorted_github_library_versions(items) : items
31+
source == :github ? sorted_github_library_versions(items) : items
32+
end
3133
end
3234

3335
def name

app/views/shared/library_list.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<h3>All matches</h3>
2121
<% end %>
2222
<div class="libraries">
23-
<% if @collection.count == 0 %>
23+
<% if @collection.empty? %>
2424
<div class="row">No matches found.</div>
2525
<% end %>
2626
<%= render partial: "shared/library", collection: @collection %>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class AddLowerNameIndexToLibraries < ActiveRecord::Migration[8.0]
2+
def change
3+
# Add a functional index for efficient alphabetical filtering
4+
# This improves the LIKE 'a%' queries used in AlphaIndexable concern
5+
add_index :libraries, "lower(name) varchar_pattern_ops", name: "index_libraries_on_lower_name_pattern"
6+
end
7+
end

0 commit comments

Comments
 (0)