Отправь asyn c ответ и не получай зомб ie pids - PullRequest
0 голосов
/ 04 марта 2020

Я стремлюсь к тому, чтобы клиент curl отправлял http req в Go API, а Go API - (1. запускает фоновую оболочку, 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 created
cmd.Wait()

//do bunch of other commands here that take 30+ seconds

l.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 Ответ

2 голосов
/ 04 марта 2020

Ответ будет завершен, когда обработчик HTTP вернется, поэтому, если вы хотите запустить задание, которое будет продолжаться, вы должны сделать это в отдельной программе. Вы можете запустить программу, как только начнется процесс оболочки, используя что-то вроде этого:

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
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...