Go Executable在返回结果之前等待goroutine完成

时间:2017-12-15 14:44:04

标签: bash go goroutine

有人可以向我解释为什么第一个go可执行文件会立即返回http请求,第二个则不会。

第一个很明显地从Github网络钩子中搜索一个帖子。如果收到的钩子是我们正在侦听的repo和分支,它会执行一个bash脚本来获取新代码并重建docker容器。这个脚本大约需要5分钟才能执行,并且每次运行它都会完美地执行它,但是go进程会等到bash脚本完成后再将响应返回给服务器,所以Github认为请求超时。

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "strings"
    "os/exec"
)

type Repository struct {
    ID int `json:"id"`
    Name string `json:"name"`
}

//Webhook Object
type Webhook struct {
    Ref     string `json:"ref"`
    Repo    Repository `json:"repository"`
}

func valid(str string) bool {
    var arr[7] string
    arr[0] = "Repo1"
    arr[1] = "Repo2"
    arr[2] = "Repo3"
    arr[3] = "Repo4"
    arr[4] = "Repo5"
    for _, a := range arr {
        if a == str {
            return true
        }
    }
    return false
}

func rebuild() {
    exec.Command("rebuild")
}

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        var webhook Webhook
        if r.Body == nil {
                http.Error(w, "Please send a request body", 400)
            return
        }

        err := json.NewDecoder(r.Body).Decode(&webhook)
        if err != nil {
            http.Error(w, err.Error(), 400)
            return
        }
        if strings.Index(webhook.Ref, "master") != -1 {
            if valid(webhook.Repo.Name) {
                fmt.Fprintf(w, "%s", "success");
                go rebuild()
            }
        }
    })
    log.Fatal(http.ListenAndServe(":8088", nil))
}

这个第二个可执行文件也运行一个bash脚本。这个bash脚本与第一个脚本完全不同,但它确实运行了第一个最耗时的部分,它是Angular应用程序的AOT编译。

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "os/exec"
)

type Repository struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

//Webhook Object
type Webhook struct {
    Ref  string     `json:"ref"`
    Repo Repository `json:"repository"`
}

func rebuild() {
    var buff bytes.Buffer
    out, err := exec.Command("/bin/bash", "/Users/myuser/test.sh").Output()
    if err != nil {
        buff.WriteString("Something went wrong: ")
        fmt.Println(buff.String())
        log.Fatal(err)
    }
    buff.Write(out)
    fmt.Println(buff.String())
}

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        var webhook Webhook
        if r.Body == nil {
            http.Error(w, "Please send a request body", 400)
            return
        }

        err := json.NewDecoder(r.Body).Decode(&webhook)
        if err != nil {
            http.Error(w, err.Error(), 400)
            return
        }
        fmt.Fprintf(w, "%s", "Success")
        go rebuild()
    })
    log.Fatal(http.ListenAndServe(":8088", nil))
}

第一次在EC2实例上运行时,返回275秒。第二个在本地运行时,返回约20ms。我不能为我的生活弄清楚为什么第一个人在返回之前等待goroutine完成,但第二个没有。

非常感谢任何帮助或见解。

编辑: 日志打印以下内容:

Request Recieved At: 2017-12-15T15:17:30Z
Response sent At: 2017-12-15T15:17:30Z
Rebuild Started At: 2017-12-15T15:17:30Z
Rebuild Completed At: 2017-12-15T15:22:04Z

0 个答案:

没有答案