This PR adds a new table named commit status summary to reduce queries from the commit status table. After this change, commit status summary table will be used for the final result, commit status table will be for details. ---------
Showing the changes to services/repository/commitstatus/commitstatus.go (1 of 6 files). Show all
Unified · Split
| @@ -7,6 +7,7 @@ import ( · 6 unmodified lines | ||
| 7 | 7 | "context" |
| 8 | 8 | "crypto/sha256" |
| 9 | 9 | "fmt" |
| 10 | + "slices" | |
| 10 | 11 | |
| 11 | 12 | "code.gitea.io/gitea/models/db" |
| 12 | 13 | git_model "code.gitea.io/gitea/models/git" |
| @@ -59,13 +60,19 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creato · 46 unmodified lines | ||
| 59 | 60 | sha = commit.ID.String() |
| 60 | 61 | } |
| 61 | 62 | |
| 62 | − if err := git_model.NewCommitStatus(ctx, git_model.NewCommitStatusOptions{ | |
| 63 | − Repo: repo, | |
| 64 | − Creator: creator, | |
| 65 | − SHA: commit.ID, | |
| 66 | − CommitStatus: status, | |
| 63 | + if err := db.WithTx(ctx, func(ctx context.Context) error { | |
| 64 | + if err := git_model.NewCommitStatus(ctx, git_model.NewCommitStatusOptions{ | |
| 65 | + Repo: repo, | |
| 66 | + Creator: creator, | |
| 67 | + SHA: commit.ID, | |
| 68 | + CommitStatus: status, | |
| 69 | + }); err != nil { | |
| 70 | + return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err) | |
| 71 | + } | |
| 72 | + | |
| 73 | + return git_model.UpdateCommitStatusSummary(ctx, repo.ID, commit.ID.String()) | |
| 67 | 74 | }); err != nil { |
| 68 | − return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err) | |
| 75 | + return err | |
| 69 | 76 | } |
| 70 | 77 | |
| 71 | 78 | defaultBranchCommit, err := gitRepo.GetBranchCommit(repo.DefaultBranch) |
| @@ -114,8 +121,35 @@ func FindReposLastestCommitStatuses(ctx context.Context, repos []*repo_model.Rep · 42 unmodified lines | ||
| 114 | 121 | return nil, fmt.Errorf("FindBranchesByRepoAndBranchName: %v", err) |
| 115 | 122 | } |
| 116 | 123 | |
| 124 | + var repoSHAs []git_model.RepoSHA | |
| 125 | + for id, sha := range repoIDsToLatestCommitSHAs { | |
| 126 | + repoSHAs = append(repoSHAs, git_model.RepoSHA{RepoID: id, SHA: sha}) | |
| 127 | + } | |
| 128 | + | |
| 129 | + summaryResults, err := git_model.GetLatestCommitStatusForRepoAndSHAs(ctx, repoSHAs) | |
| 130 | + if err != nil { | |
| 131 | + return nil, fmt.Errorf("GetLatestCommitStatusForRepoAndSHAs: %v", err) | |
| 132 | + } | |
| 133 | + | |
| 134 | + for _, summary := range summaryResults { | |
| 135 | + for i, repo := range repos { | |
| 136 | + if repo.ID == summary.RepoID { | |
| 137 | + results[i] = summary | |
| 138 | + _ = slices.DeleteFunc(repoSHAs, func(repoSHA git_model.RepoSHA) bool { | |
| 139 | + return repoSHA.RepoID == repo.ID | |
| 140 | + }) | |
| 141 | + if results[i].State != "" { | |
| 142 | + if err := updateCommitStatusCache(ctx, repo.ID, repo.DefaultBranch, results[i].State); err != nil { | |
| 143 | + log.Error("updateCommitStatusCache[%d:%s] failed: %v", repo.ID, repo.DefaultBranch, err) | |
| 144 | + } | |
| 145 | + } | |
| 146 | + break | |
| 147 | + } | |
| 148 | + } | |
| 149 | + } | |
| 150 | + | |
| 117 | 151 | // call the database O(1) times to get the commit statuses for all repos |
| 118 | − repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoIDsToLatestCommitSHAs, db.ListOptionsAll) | |
| 152 | + repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoSHAs) | |
| 119 | 153 | if err != nil { |
| 120 | 154 | return nil, fmt.Errorf("GetLatestCommitStatusForPairs: %v", err) |
| 121 | 155 | } |