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
Files
14
@@ -12,6 +12,8 @@ class UserRecentEventsFinder
attr_reader :current_user, :target_user, :params
LIMIT = 20
def initialize(current_user, target_user, params = {})
@current_user = current_user
@target_user = target_user
@@ -19,15 +21,34 @@ def initialize(current_user, target_user, params = {})
end
def execute
target_user
.recent_events
.merge(projects_for_current_user)
.references(:project)
events(offset: params[:offset] || 0)
.joins(:project)
.with_associations
.limit_recent(20, params[:offset])
.limit_recent(LIMIT, params[:offset])
end
def projects_for_current_user
ProjectsFinder.new(current_user: current_user).execute
private
def events(offset: 0)
authorized_projects = ProjectAuthorization
.where(user: current_user)
.select(:project_id)
interacted_projects = UserInteractedProjects
.joins(:project)
.where(user: target_user, projects: { visibility_level: [10, 20] })
.select(:project_id)
projects = Gitlab::SQL::Union.new([authorized_projects, interacted_projects]).to_sql
lateral = Event.where(author: target_user)
.where('events.project_id = projects_for_lateral.project_id')
.order('id DESC')
.limit(LIMIT + Integer(offset)) # Consider this is used in LATERAL JOIN and we paginate/offset the outer relation
.to_sql
# Workaround for https://github.com/rails/rails/issues/24193
sql = "(#{projects}) AS projects_for_lateral JOIN LATERAL (#{lateral}) AS #{Event.table_name} ON true"
Event.from([Arel.sql(sql)])
end
end
Loading