changeset 5763:20a094053606

pullrequests: optimize iteration over reviewers - avoid fetching users one by one .reviewers was mainly used for iteration and then dereferencing .user one by one. That gave lots of queries and round trips to the database and was slow. Instead, do something else. Either query directly or use a new method for getting the list of reviewer users. Reviewers will explicitly be shown in the order they have been added (assuming database id's are monotonic).
author Mads Kiilerich <madski@unity3d.com>
date Mon, 14 Mar 2016 16:17:46 +0100
parents d36dc6617d87
children b03233c4a438
files kallithea/controllers/pullrequests.py kallithea/model/changeset_status.py kallithea/model/comment.py kallithea/model/db.py
diffstat 4 files changed, 18 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/controllers/pullrequests.py	Mon Mar 14 16:17:46 2016 +0100
+++ b/kallithea/controllers/pullrequests.py	Mon Mar 14 16:17:46 2016 +0100
@@ -182,8 +182,11 @@
             return False
 
         owner = self.authuser.user_id == pull_request.user_id
-        reviewer = self.authuser.user_id in [x.user_id for x in
-                                                   pull_request.reviewers]
+        reviewer = PullRequestReviewers.query() \
+            .filter(PullRequestReviewers.pull_request == pull_request) \
+            .filter(PullRequestReviewers.user_id == self.authuser.user_id) \
+            .count() != 0
+
         return self.authuser.admin or owner or reviewer
 
     @LoginRequired()
--- a/kallithea/model/changeset_status.py	Mon Mar 14 16:17:46 2016 +0100
+++ b/kallithea/model/changeset_status.py	Mon Mar 14 16:17:46 2016 +0100
@@ -98,14 +98,14 @@
         pull_request_reviewers = []
         pull_request_pending_reviewers = []
         relevant_statuses = []
-        for r in pull_request.reviewers:
-            st = cs_statuses.get(r.user.username)
+        for user in pull_request.get_reviewer_users():
+            st = cs_statuses.get(user.username)
             relevant_statuses.append(st)
             if not st or st.status in (ChangesetStatus.STATUS_NOT_REVIEWED,
                                        ChangesetStatus.STATUS_UNDER_REVIEW):
                 st = None
-                pull_request_pending_reviewers.append(r.user)
-            pull_request_reviewers.append((r.user, st))
+                pull_request_pending_reviewers.append(user)
+            pull_request_reviewers.append((user, st))
 
         result = self._calculate_status(relevant_statuses)
 
--- a/kallithea/model/comment.py	Mon Mar 14 16:17:46 2016 +0100
+++ b/kallithea/model/comment.py	Mon Mar 14 16:17:46 2016 +0100
@@ -139,7 +139,7 @@
             recipients += [pull_request.owner]
 
             # add the reviewers to notification
-            recipients += [x.user for x in pull_request.reviewers]
+            recipients += pull_request.get_reviewer_users()
 
             #set some variables for email notification
             email_kwargs = {
--- a/kallithea/model/db.py	Mon Mar 14 16:17:46 2016 +0100
+++ b/kallithea/model/db.py	Mon Mar 14 16:17:46 2016 +0100
@@ -2322,6 +2322,14 @@
     comments = relationship('ChangesetComment', order_by='ChangesetComment.comment_id',
                              cascade="all, delete-orphan")
 
+    def get_reviewer_users(self):
+        """Like .reviewers, but actually returning the users"""
+        return User.query() \
+            .join(PullRequestReviewers) \
+            .filter(PullRequestReviewers.pull_request == self) \
+            .order_by(PullRequestReviewers.pull_requests_reviewers_id) \
+            .all()
+
     def is_closed(self):
         return self.status == self.STATUS_CLOSED