Skip to content
Snippets Groups Projects

Improve database response time for listing user activity

Merged Andreas Brandl requested to merge 40525-listing-user-activity-timeouts into master
All threads resolved!
Files
14
@@ -12,6 +12,8 @@ class UserRecentEventsFinder
@@ -12,6 +12,8 @@ class UserRecentEventsFinder
attr_reader :current_user, :target_user, :params
attr_reader :current_user, :target_user, :params
 
LIMIT = 20
 
def initialize(current_user, target_user, params = {})
def initialize(current_user, target_user, params = {})
@current_user = current_user
@current_user = current_user
@target_user = target_user
@target_user = target_user
@@ -19,15 +21,44 @@ class UserRecentEventsFinder
@@ -19,15 +21,44 @@ class UserRecentEventsFinder
end
end
def execute
def execute
target_user
recent_events(params[:offset] || 0)
.recent_events
.joins(:project)
.merge(projects_for_current_user)
.references(:project)
.with_associations
.with_associations
.limit_recent(20, params[:offset])
.limit_recent(LIMIT, params[:offset])
 
end
 
 
private
 
 
def recent_events(offset)
 
sql = <<~SQL
 
(#{projects}) AS projects_for_join
 
JOIN (#{target_events.to_sql}) AS #{Event.table_name}
 
ON #{Event.table_name}.project_id = projects_for_join.id
 
SQL
 
 
# Workaround for https://github.com/rails/rails/issues/24193
 
Event.from([Arel.sql(sql)])
end
end
def projects_for_current_user
def target_events
ProjectsFinder.new(current_user: current_user).execute
Event.where(author: target_user)
 
end
 
 
def projects
 
# Compile a list of projects `current_user` interacted with
 
# and `target_user` is allowed to see.
 
 
authorized = target_user
 
.project_interactions
 
.joins(:project_authorizations)
 
.where(project_authorizations: { user: current_user })
 
.select(:id)
 
 
visible = target_user
 
.project_interactions
 
.where(visibility_level: [Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::PUBLIC])
 
.select(:id)
 
 
Gitlab::SQL::Union.new([authorized, visible]).to_sql
end
end
end
end
Loading