1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-23 02:38:35 +00:00

Performance improvements for pull request list page (#29900) (#29972)

This PR will avoid load pullrequest.Issue twice in pull request list
page. It will reduce x times database queries for those WIP pull
requests.

Partially fix #29585
Backport #29900
This commit is contained in:
Lunny Xiao
2024-03-22 09:58:04 +08:00
committed by GitHub
parent c03b1e2854
commit 6ef986d474
14 changed files with 85 additions and 49 deletions

View File

@@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder"
"xorm.io/xorm"
@@ -821,3 +822,31 @@ func UpdateNotificationStatuses(ctx context.Context, user *user_model.User, curr
Update(n)
return err
}
// LoadIssuePullRequests loads all issues' pull requests if possible
func (nl NotificationList) LoadIssuePullRequests(ctx context.Context) error {
issues := make(map[int64]*issues_model.Issue, len(nl))
for _, notification := range nl {
if notification.Issue != nil && notification.Issue.IsPull && notification.Issue.PullRequest == nil {
issues[notification.Issue.ID] = notification.Issue
}
}
if len(issues) == 0 {
return nil
}
pulls, err := issues_model.GetPullRequestByIssueIDs(ctx, util.KeysOfMap(issues))
if err != nil {
return err
}
for _, pull := range pulls {
if issue := issues[pull.IssueID]; issue != nil {
issue.PullRequest = pull
issue.PullRequest.Issue = issue
}
}
return nil
}

View File

@@ -200,20 +200,6 @@ func (issue *Issue) IsTimetrackerEnabled(ctx context.Context) bool {
return issue.Repo.IsTimetrackerEnabled(ctx)
}
// GetPullRequest returns the issue pull request
func (issue *Issue) GetPullRequest() (pr *PullRequest, err error) {
if !issue.IsPull {
return nil, fmt.Errorf("Issue is not a pull request")
}
pr, err = GetPullRequestByIssueID(db.DefaultContext, issue.ID)
if err != nil {
return nil, err
}
pr.Issue = issue
return pr, err
}
// LoadPoster loads poster
func (issue *Issue) LoadPoster(ctx context.Context) (err error) {
if issue.Poster == nil && issue.PosterID != 0 {

View File

@@ -370,6 +370,9 @@ func (issues IssueList) LoadPullRequests(ctx context.Context) error {
for _, issue := range issues {
issue.PullRequest = pullRequestMaps[issue.ID]
if issue.PullRequest != nil {
issue.PullRequest.Issue = issue
}
}
return nil
}

View File

@@ -212,3 +212,12 @@ func HasMergedPullRequestInRepo(ctx context.Context, repoID, posterID int64) (bo
Limit(1).
Get(new(Issue))
}
// GetPullRequestByIssueIDs returns all pull requests by issue ids
func GetPullRequestByIssueIDs(ctx context.Context, issueIDs []int64) (PullRequestList, error) {
prs := make([]*PullRequest, 0, len(issueIDs))
return prs, db.GetEngine(ctx).
Where("issue_id > 0").
In("issue_id", issueIDs).
Find(&prs)
}

View File

@@ -240,11 +240,11 @@ type CreateReviewOptions struct {
// IsOfficialReviewer check if at least one of the provided reviewers can make official reviews in issue (counts towards required approvals)
func IsOfficialReviewer(ctx context.Context, issue *Issue, reviewer *user_model.User) (bool, error) {
pr, err := GetPullRequestByIssueID(ctx, issue.ID)
if err != nil {
if err := issue.LoadPullRequest(ctx); err != nil {
return false, err
}
pr := issue.PullRequest
rule, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch)
if err != nil {
return false, err
@@ -272,11 +272,10 @@ func IsOfficialReviewer(ctx context.Context, issue *Issue, reviewer *user_model.
// IsOfficialReviewerTeam check if reviewer in this team can make official reviews in issue (counts towards required approvals)
func IsOfficialReviewerTeam(ctx context.Context, issue *Issue, team *organization.Team) (bool, error) {
pr, err := GetPullRequestByIssueID(ctx, issue.ID)
if err != nil {
if err := issue.LoadPullRequest(ctx); err != nil {
return false, err
}
pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch)
pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, issue.PullRequest.BaseRepoID, issue.PullRequest.BaseBranch)
if err != nil {
return false, err
}