有人可以向我解释为什么第一个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