Skip to content

Commit f034ee6

Browse files
authored
PullService lock via pullID (#19520)
* lock pull on git&db actions ... * add TODO notes * rename prQueue 2 prPatchCheckerQueue * fmt
1 parent e933f31 commit f034ee6

File tree

6 files changed

+21
-2
lines changed

6 files changed

+21
-2
lines changed

services/pull/check.go

+2
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ func handle(data ...queue.Data) []queue.Data {
317317
}
318318

319319
func testPR(id int64) {
320+
pullWorkingPool.CheckIn(fmt.Sprint(id))
321+
defer pullWorkingPool.CheckOut(fmt.Sprint(id))
320322
ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("Test PR[%d] from patch checking queue", id))
321323
defer finished()
322324

services/pull/merge.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import (
3434

3535
// Merge merges pull request to base repository.
3636
// Caller should check PR is ready to be merged (review and status checks)
37-
// FIXME: add repoWorkingPull make sure two merges does not happen at same time.
3837
func Merge(pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) error {
3938
if err := pr.LoadHeadRepo(); err != nil {
4039
log.Error("LoadHeadRepo: %v", err)
@@ -44,6 +43,9 @@ func Merge(pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Repos
4443
return fmt.Errorf("LoadBaseRepo: %v", err)
4544
}
4645

46+
pullWorkingPool.CheckIn(fmt.Sprint(pr.ID))
47+
defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID))
48+
4749
prUnit, err := pr.BaseRepo.GetUnit(unit.TypePullRequests)
4850
if err != nil {
4951
log.Error("pr.BaseRepo.GetUnit(unit.TypePullRequests): %v", err)
@@ -726,6 +728,9 @@ func CheckPullBranchProtections(ctx context.Context, pr *models.PullRequest, ski
726728

727729
// MergedManually mark pr as merged manually
728730
func MergedManually(pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, commitID string) error {
731+
pullWorkingPool.CheckIn(fmt.Sprint(pr.ID))
732+
defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID))
733+
729734
if err := db.WithTx(func(ctx context.Context) error {
730735
prUnit, err := pr.BaseRepo.GetUnitCtx(ctx, unit.TypePullRequests)
731736
if err != nil {

services/pull/pull.go

+7
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ import (
2525
"code.gitea.io/gitea/modules/notification"
2626
"code.gitea.io/gitea/modules/process"
2727
"code.gitea.io/gitea/modules/setting"
28+
"code.gitea.io/gitea/modules/sync"
2829
issue_service "code.gitea.io/gitea/services/issue"
2930
)
3031

32+
// TODO: use clustered lock (unique queue? or *abuse* cache)
33+
var pullWorkingPool = sync.NewExclusivePool()
34+
3135
// NewPullRequest creates new pull request with labels for repository.
3236
func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *models.Issue, labelIDs []int64, uuids []string, pr *models.PullRequest, assigneeIDs []int64) error {
3337
if err := TestPatch(pr); err != nil {
@@ -124,6 +128,9 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode
124128

125129
// ChangeTargetBranch changes the target branch of this pull request, as the given user.
126130
func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_model.User, targetBranch string) (err error) {
131+
pullWorkingPool.CheckIn(fmt.Sprint(pr.ID))
132+
defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID))
133+
127134
// Current target branch is already the same
128135
if pr.BaseBranch == targetBranch {
129136
return nil

services/pull/update.go

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ func Update(ctx context.Context, pull *models.PullRequest, doer *user_model.User
2323
style repo_model.MergeStyle
2424
)
2525

26+
pullWorkingPool.CheckIn(fmt.Sprint(pull.ID))
27+
defer pullWorkingPool.CheckOut(fmt.Sprint(pull.ID))
28+
2629
if rebase {
2730
pr = pull
2831
style = repo_model.MergeStyleRebaseUpdate

services/repository/transfer.go

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
)
2020

2121
// repoWorkingPool represents a working pool to order the parallel changes to the same repository
22+
// TODO: use clustered lock (unique queue? or *abuse* cache)
2223
var repoWorkingPool = sync.NewExclusivePool()
2324

2425
// TransferOwnership transfers all corresponding setting from old user to new one.

services/wiki/wiki.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ import (
2727

2828
var (
2929
reservedWikiNames = []string{"_pages", "_new", "_edit", "raw"}
30-
wikiWorkingPool = sync.NewExclusivePool()
30+
// TODO: use clustered lock (unique queue? or *abuse* cache)
31+
wikiWorkingPool = sync.NewExclusivePool()
3132
)
3233

3334
func nameAllowed(name string) error {

0 commit comments

Comments
 (0)