From fd28954e48e8d7453966edff95e2866f12c3b25a Mon Sep 17 00:00:00 2001 From: Ronmi Ren Date: Sun, 12 Jan 2025 22:59:11 +0800 Subject: [PATCH] webhook will be lock by repo to prevent re-entrance. --- lib/hook.go | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/hook.go b/lib/hook.go index 30cfc98..b0b6bb4 100644 --- a/lib/hook.go +++ b/lib/hook.go @@ -15,6 +15,7 @@ import ( "os/exec" "path" "path/filepath" + "sync" ) type WebhookCFG struct { @@ -112,7 +113,21 @@ func (c *WebhookCFG) clone(user, repo string) (err error) { 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) { + unlock := c.lock(user, repo) + defer unlock() + gitDir := c.gitDir(user, repo) if _, err = os.Stat(gitDir); os.IsNotExist(err) { 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 = user[:len(user)-1] - fmt.Println("Pulling ", user, repo) - err = c.download(user, repo) - if err != nil { - fmt.Println("Failed to download repository: ", err) - return - } + go func() { + fmt.Println("Pulling ", user, repo) + err = c.download(user, repo) + if err != nil { + fmt.Println("Failed to download repository: ", err) + return + } + }() } func UseWebhook(bind string, cfg *WebhookCFG) (*http.Server, error) {