loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

port(gitea#31954): Add lock for parallel maven upload (#6513)

Backport #31851
Fix #30171

---

Fixes https://github.com/go-gitea/gitea/issues/30171, this is also a
issue in Forgejo. Backport the implementation that uses the existing
sync module which does not work for multiple instances which is
perfectly fine for Forgejo for now.

(cherry picked from commit 9c990ac043a0167dc59f1c822988ed2316f7c1df)

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6513
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>

Gusted 46e15e57 a22c8248

+39
+6
routers/api/packages/maven/maven.go
··· 24 24 "code.gitea.io/gitea/modules/log" 25 25 packages_module "code.gitea.io/gitea/modules/packages" 26 26 maven_module "code.gitea.io/gitea/modules/packages/maven" 27 + "code.gitea.io/gitea/modules/sync" 27 28 "code.gitea.io/gitea/routers/api/packages/helper" 28 29 "code.gitea.io/gitea/services/context" 29 30 packages_service "code.gitea.io/gitea/services/packages" ··· 228 229 helper.ServePackageFile(ctx, s, u, pf, opts) 229 230 } 230 231 232 + var mavenUploadLock = sync.NewExclusivePool() 233 + 231 234 // UploadPackageFile adds a file to the package. If the package does not exist, it gets created. 232 235 func UploadPackageFile(ctx *context.Context) { 233 236 params, err := extractPathParameters(ctx) ··· 245 248 } 246 249 247 250 packageName := params.GroupID + "-" + params.ArtifactID 251 + 252 + mavenUploadLock.CheckIn(packageName) 253 + defer mavenUploadLock.CheckOut(packageName) 248 254 249 255 buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body) 250 256 if err != nil {
+33
tests/integration/api_packages_maven_test.go
··· 8 8 "net/http" 9 9 "strconv" 10 10 "strings" 11 + "sync" 11 12 "testing" 12 13 13 14 "code.gitea.io/gitea/models/db" ··· 254 255 assert.NotContains(t, resp.Body.String(), "Internal server error") 255 256 }) 256 257 } 258 + 259 + func TestPackageMavenConcurrent(t *testing.T) { 260 + defer tests.PrepareTestEnv(t)() 261 + 262 + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) 263 + 264 + groupID := "com.gitea" 265 + artifactID := "test-project" 266 + packageVersion := "1.0.1" 267 + 268 + root := fmt.Sprintf("/api/packages/%s/maven/%s/%s", user.Name, strings.ReplaceAll(groupID, ".", "/"), artifactID) 269 + 270 + putFile := func(t *testing.T, path, content string, expectedStatus int) { 271 + req := NewRequestWithBody(t, "PUT", root+path, strings.NewReader(content)). 272 + AddBasicAuth(user.Name) 273 + MakeRequest(t, req, expectedStatus) 274 + } 275 + 276 + t.Run("Concurrent Upload", func(t *testing.T) { 277 + defer tests.PrintCurrentTest(t)() 278 + 279 + var wg sync.WaitGroup 280 + for i := 0; i < 10; i++ { 281 + wg.Add(1) 282 + go func(i int) { 283 + putFile(t, fmt.Sprintf("/%s/%s.jar", packageVersion, strconv.Itoa(i)), "test", http.StatusCreated) 284 + wg.Done() 285 + }(i) 286 + } 287 + wg.Wait() 288 + }) 289 + }