Skip to content

Commit

Permalink
Fix upload maven pacakge parallelly (#31851)
Browse files Browse the repository at this point in the history
Use globallock for maven package uploads.

Thanks @tlusser for the test code.

Depends on ~#31813~
  • Loading branch information
lunny authored Sep 21, 2024
1 parent ebfde84 commit 5de4173
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
13 changes: 13 additions & 0 deletions routers/api/packages/maven/maven.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"strings"

packages_model "code.gitea.io/gitea/models/packages"
"code.gitea.io/gitea/modules/globallock"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
packages_module "code.gitea.io/gitea/modules/packages"
Expand Down Expand Up @@ -223,6 +224,10 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool
helper.ServePackageFile(ctx, s, u, pf, opts)
}

func mavenPkgNameKey(packageName string) string {
return "pkg_maven_" + packageName
}

// UploadPackageFile adds a file to the package. If the package does not exist, it gets created.
func UploadPackageFile(ctx *context.Context) {
params, err := extractPathParameters(ctx)
Expand All @@ -241,6 +246,14 @@ func UploadPackageFile(ctx *context.Context) {

packageName := params.GroupID + "-" + params.ArtifactID

// for the same package, only one upload at a time
releaser, err := globallock.Lock(ctx, mavenPkgNameKey(packageName))
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
defer releaser()

buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
Expand Down
33 changes: 33 additions & 0 deletions tests/integration/api_packages_maven_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"strconv"
"strings"
"sync"
"testing"

"code.gitea.io/gitea/models/db"
Expand Down Expand Up @@ -252,3 +253,35 @@ func TestPackageMaven(t *testing.T) {
assert.True(t, test.IsNormalPageCompleted(resp.Body.String()))
})
}

func TestPackageMavenConcurrent(t *testing.T) {
defer tests.PrepareTestEnv(t)()

user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})

groupID := "com.gitea"
artifactID := "test-project"
packageVersion := "1.0.1"

root := fmt.Sprintf("/api/packages/%s/maven/%s/%s", user.Name, strings.ReplaceAll(groupID, ".", "/"), artifactID)

putFile := func(t *testing.T, path, content string, expectedStatus int) {
req := NewRequestWithBody(t, "PUT", root+path, strings.NewReader(content)).
AddBasicAuth(user.Name)
MakeRequest(t, req, expectedStatus)
}

t.Run("Concurrent Upload", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()

var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
putFile(t, fmt.Sprintf("/%s/%s.jar", packageVersion, strconv.Itoa(i)), "test", http.StatusCreated)
wg.Done()
}(i)
}
wg.Wait()
})
}

0 comments on commit 5de4173

Please sign in to comment.