Skip to content

Commit

Permalink
fix: Disable concurrent package uploads per type
Browse files Browse the repository at this point in the history
  • Loading branch information
tlusser-inv committed Apr 15, 2024
1 parent d6b0d0e commit 02999c3
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
19 changes: 19 additions & 0 deletions services/packages/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"io"
"net/url"
"strings"
"sync"

"code.gitea.io/gitea/models/db"
packages_model "code.gitea.io/gitea/models/packages"
Expand All @@ -31,6 +32,17 @@ var (
ErrQuotaTotalCount = errors.New("maximum allowed package count exceeded")
)

var mutexMap sync.Map

func getOrCreateMutex(name string) *sync.Mutex {
mutex, ok := mutexMap.Load(name)
if !ok {
newMutex := &sync.Mutex{}
mutex, _ = mutexMap.LoadOrStore(name, newMutex)
}
return mutex.(*sync.Mutex)
}

// PackageInfo describes a package
type PackageInfo struct {
Owner *user_model.User
Expand Down Expand Up @@ -76,6 +88,13 @@ func CreatePackageOrAddFileToExisting(ctx context.Context, pvci *PackageCreation
}

func createPackageAndAddFile(ctx context.Context, pvci *PackageCreationInfo, pfci *PackageFileCreationInfo, allowDuplicate bool) (*packages_model.PackageVersion, *packages_model.PackageFile, error) {

mutex := getOrCreateMutex(pvci.PackageType.Name())
mutex.Lock()
defer func() {
mutex.Unlock()
}()

dbCtx, committer, err := db.TxContext(ctx)
if err != nil {
return nil, nil, 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 @@ -242,3 +243,35 @@ func TestPackageMaven(t *testing.T) {
putFile(t, fmt.Sprintf("/%s/maven-metadata.xml", snapshotVersion), "test-overwrite", http.StatusCreated)
})
}

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))
req = AddBasicAuthHeader(req, 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 02999c3

Please sign in to comment.