我的目标是 curl 客户端向 Go API 发送 http req,而 Go API 确实如此(1. 运行后台 shell,2. 立即向客户端返回响应,但 3. 继续在后台运行第 1 点服务器端命令)。问题是第 2 点没有立即返回给客户端,客户端仅在第 3 点完成后才得到响应我试过:import ( "fmt" "io" "io/ioutil" "net/http" "os" "os/exec" "log" "strings" "flag" "strconv" "crypto/tls" "crypto/x509" "github.com/gorilla/handlers" "github.com/gorilla/mux" "github.com/go-ldap/ldap" "regexp" "errors" "encoding/base64" "time")func insert(w http.ResponseWriter, r *http.Request) (error) {fullcmd := fmt.Sprintf("/home/ec2-user/spark_home/bin/spark-submit %s", "dgs")cmd := exec.Command("/bin/sh", "-c", fullcmd)err4 := cmd.Start()if err4 != nil { e1 := fmt.Sprintf("Error") l.Printf(e1) http.Error(w, e1, http.StatusInternalServerError) return err4} else { l.Printf("The data is being ingested asynchronously in the background \n") fmt.Fprintf(w, "request received. The data is being ingested asynchronously in the background \n") w.Header().Set("Content-Type", "text/plain") w.Write([]byte(fmt.Sprintf("request received. The data is being ingested asynchronously in the background \n")))}//wait for the spark command to finish, need to Wait() otherwise zombie/orphan pid is createdcmd.Wait()//do bunch of other commands here that take 30+ secondsl.Printf("success") return nil}r := mux.NewRouter() r.HandleFunc("/test", insert).Methods(http.MethodPost) http.Handle("/", r) server := &http.Server{ Addr: ":" + strconv.Itoa(*port), Handler: handlers.LoggingHandler(os.Stdout, http.DefaultServeMux), TLSConfig: tlsConfig, } server.ListenAndServeTLS(TLS_SERVER_CERTFILE, TLS_SERVER_KEYFILE)
1 回答
UYOU
TA贡献1878条经验 获得超4个赞
当 HTTP 处理程序返回时,响应将完成,因此如果您想启动一个将继续的作业,您必须在单独的 goroutine 中执行此操作。您可以在 shell 进程启动后立即启动 goroutine,使用如下所示:
func insert(w http.ResponseWriter, r *http.Request) (error) {
...
err4 := cmd.Start()
if err4 != nil {
...
}
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintf(w, "request received. The data is being ingested asynchronously in the background \n")
go func() {
cmd.Wait()
// Do other stuff
}()
return nil
}
- 1 回答
- 0 关注
- 108 浏览
添加回答
举报
0/150
提交
取消