Commit a2babf32 authored by Francisco Lopez's avatar Francisco Lopez

More preloading improvement and added batch count services

parent dd562ae7
......@@ -12,8 +12,8 @@ class BaseCountService
Rails.cache.fetch(cache_key, cache_options) { uncached_count }.to_i
end
def refresh_cache
Rails.cache.write(cache_key, uncached_count, raw: raw?)
def refresh_cache(&block)
Rails.cache.write(cache_key, block_given? ? yield : uncached_count, raw: raw?)
end
def uncached_count
......
module Projects
class BatchCountService
def initialize(projects)
@projects = projects
end
def count
@projects.map do |project|
[project.id, current_count_service(project).count]
end.to_h
end
def refresh_cache
@projects.each do |project|
current_count_service(project).refresh_cache { global_count[project.id].to_i }
end
end
def current_count_service(project)
if defined? @service
@service.project = project
else
count_service.new(project)
end
end
def global_count(project)
raise NotImplementedError, 'global_count must be implemented and return an hash indexed by the project id'
end
def count_service
raise NotImplementedError, 'count_service must be implemented and return a Projects::CountService object'
end
end
end
module Projects
# Service class for getting and caching the number of forks of several projects
class BatchForksCountService < Projects::BatchCountService
def global_count
@global_count ||= ForkedProjectLink.where(forked_from_project: @projects.map(&:id))
.group(:forked_from_project_id)
.count
end
def count_service
::Projects::ForksCountService
end
end
end
module Projects
# Service class for getting and caching the number of forks of several projects
class BatchOpenIssuesCountService < Projects::BatchCountService
def global_count
@global_count ||= Issue.opened.public_only
.where(project: @projects.map(&:id))
.group(:project_id)
.count
end
def count_service
::Projects::OpenIssuesCountService
end
end
end
......@@ -7,6 +7,8 @@ module Projects
# all caches.
VERSION = 1
attr_accessor :project
def initialize(project)
@project = project
end
......
......@@ -52,6 +52,24 @@ module API
groups
end
def find_group_projects(params)
group = find_group!(params[:id])
projects = GroupProjectsFinder.new(group: group, current_user: current_user, params: project_finder_params).execute
projects = projects.preload(:project_feature, :route, :group)
.preload(namespace: [:route, :owner],
tags: :taggings,
project_group_links: :group,
fork_network: :root_project,
forked_project_link: :forked_from_project,
forked_from_project: [:route, :forks, namespace: :route, tags: :taggings])
projects = reorder_projects(projects)
paginated_projects = paginate(projects)
projects_with_fork = paginated_projects + paginated_projects.map(&:forked_from_project).compact
::Projects::BatchForksCountService.new(projects_with_fork).refresh_cache
::Projects::BatchOpenIssuesCountService.new(paginated_projects).refresh_cache
paginated_projects
end
def present_groups(params, groups)
options = {
with: Entities::Group,
......@@ -170,12 +188,9 @@ module API
use :pagination
end
get ":id/projects" do
group = find_group!(params[:id])
projects = GroupProjectsFinder.new(group: group, current_user: current_user, params: project_finder_params).execute
projects = projects.preload(:fork_network, :forked_project_link, :project_feature, :project_group_links, :tags, :taggings, :group, :namespace, :route)
projects = reorder_projects(projects)
projects = find_group_projects(params)
entity = params[:simple] ? Entities::BasicProjectDetails : Entities::Project
present paginate(projects), with: entity, current_user: current_user
present projects, with: entity, current_user: current_user
end
desc 'Get a list of subgroups in this group.' do
......
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