webhook will be lock by repo to prevent re-entrance.

This commit is contained in:
Ronmi Ren 2025-01-12 22:59:11 +08:00
commit fd28954e48

View file

@ -15,6 +15,7 @@ import (
"os/exec" "os/exec"
"path" "path"
"path/filepath" "path/filepath"
"sync"
) )
type WebhookCFG struct { type WebhookCFG struct {
@ -112,7 +113,21 @@ func (c *WebhookCFG) clone(user, repo string) (err error) {
return return
} }
var repoLock = &sync.Map{}
func (c *WebhookCFG) lock(user, repo string) func() {
key := user + "/" + repo
lock, _ := repoLock.LoadOrStore(key, &sync.Mutex{})
m := lock.(*sync.Mutex)
m.Lock()
return m.Unlock
}
func (c *WebhookCFG) download(user, repo string) (err error) { func (c *WebhookCFG) download(user, repo string) (err error) {
unlock := c.lock(user, repo)
defer unlock()
gitDir := c.gitDir(user, repo) gitDir := c.gitDir(user, repo)
if _, err = os.Stat(gitDir); os.IsNotExist(err) { if _, err = os.Stat(gitDir); os.IsNotExist(err) {
err = c.clone(user, repo) err = c.clone(user, repo)
@ -169,12 +184,14 @@ func (c *WebhookCFG) handle(w http.ResponseWriter, r *http.Request) {
user, repo := path.Split(payload.Repository.FullName) user, repo := path.Split(payload.Repository.FullName)
user = user[:len(user)-1] user = user[:len(user)-1]
go func() {
fmt.Println("Pulling ", user, repo) fmt.Println("Pulling ", user, repo)
err = c.download(user, repo) err = c.download(user, repo)
if err != nil { if err != nil {
fmt.Println("Failed to download repository: ", err) fmt.Println("Failed to download repository: ", err)
return return
} }
}()
} }
func UseWebhook(bind string, cfg *WebhookCFG) (*http.Server, error) { func UseWebhook(bind string, cfg *WebhookCFG) (*http.Server, error) {