Skip to content

Webhook on create repository never served #7404

Closed
@davidsvantesson

Description

@davidsvantesson
  • Gitea version (or commit ref): 1.8.3 and 1.10.0+dev-27-g877df0f9f
  • Git version: 2.17.1
  • Operating system: Ubuntu 18.04.1 LTS
  • Database (use [x]):
    • PostgreSQL
    • MySQL
    • MSSQL
    • SQLite
  • Can you reproduce the bug at https://try.gitea.io:
    • Yes (provide example URL)
    • No
    • Not relevant
  • Log gist:

Description

Webhooks at repository creation is never served (possible race condition)

Steps to reproduce:

  • Adding a webhook under organization, Trigger on Custom Events.. "Repository"
  • Create a repository under the organization
    Results:
  • A hook_task is created in the database and seen in the log, but it is never handled (see screenshot)

Brief debugging:
It did not occur when running monolithic binary with sqlite directly. But running the same binary as a service with PostgreSQL caused the issue.
Then we tested to add an extra sleep in modules/webhook.go and then we didn't see the problem, see time.Sleep added below:

func DeliverHooks() {
        tasks := make([]*HookTask, 0, 10)
        err := x.Where("is_delivered=?", false).Find(&tasks)
        if err != nil {
                log.Error("DeliverHooks: %v", err)
                return
        }

        // Update hook task status.
        for _, t := range tasks {
                if err = t.deliver(); err != nil {
                        log.Error("deliver: %v", err)
                        continue
                }
        }

        // Start listening on new hook requests.
        for repoIDStr := range HookQueue.Queue() {
                log.Trace("DeliverHooks [repo_id: %v]", repoIDStr)
                HookQueue.Remove(repoIDStr)

                repoID, err := com.StrTo(repoIDStr).Int64()
                if err != nil {
                        log.Error("Invalid repo ID: %s", repoIDStr)
                        continue
                }

                tasks = make([]*HookTask, 0, 5)
                time.Sleep(5 * time.Second)
                if err := x.Where("repo_id=? AND is_delivered=?", repoID, false).Find(&tasks); err != nil {
                        log.Error("Get repository [%d] hook tasks: %v", repoID, err)
                        continue
                }
                for _, t := range tasks {
                        if err = t.deliver(); err != nil {
                                log.Error("deliver: %v", err)
                        }
                }
        }
}

Screenshots

WebHookCreateRepoRecentDeliveries

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions