User#recent_push can be improved greatly once push events have been migrated into the new format
The method User#recent_push
is implemented in a rather in-efficient way and will run a bunch of queries if any recent push events were found. This whole method can be optimised down to (more or less) the following once all push events have been migrated into the new format:
def recent_push(project_ids = nil)
# Get push events not earlier than 2 hours ago
events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours)
events = events.where(project_id: project_ids) if project_ids
mr_query = MergeRequest
.select(1)
.except(:order)
.where('created_at >= events.created_at')
.where('source_project_id = events.project_id')
.where('source_branch = push_event_payloads.ref_name')
.where(push_event_payloads: { ref_type: 'branch' })
events = events.includes(:project).recent.where('NOT EXISTS (?)', mr_query)
events.find do |event|
event.project.repository.branch_exists?(event.branch_name)
end
end
This will still require Git calls for every returned event to figure out if the branch exists, but we currently have no way around that.
We should also look into caching the results per user. Since we know which user is used for a push we can invalidate these caches when pushing.
I'm tagging this as ~AP2 since this code runs on a lot of pages.