为了账号安全,请及时绑定邮箱和手机立即绑定

发送异步响应并且不会收到僵尸 pid

发送异步响应并且不会收到僵尸 pid

Go
繁华开满天机 2022-05-18 16:49:10
我的目标是 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

}


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 108 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信