I'm writing a webserver that distributes requests to out-of-process programs in Go. I'm sending the ResponseWriter and Request datatypes through Pipes using gob.
The problem is the external process is hanging when receiving the gob.
UPDATE The gob is now successfully being sent to the external process, but now the external process is blocking at fmt.Fprintf(request.Resp, "Hello")
and freezes there.
dispreq.go
package dispreq
import (
"net/http"
)
type DispReq struct {
Resp http.ResponseWriter
Req *http.Request
}
dispatcher.go
package main
import (
"encoding/gob"
"fmt"
"net/http"
"os"
"os/exec"
"dispreq"
)
func dispatch(w http.ResponseWriter, r *http.Request) {
process := exec.Command("./hello")
pipe, piperr := process.StdinPipe()
if piperr != nil {
fmt.Fprintf(os.Stderr, piperr.Error())
return
}
encoder := gob.NewEncoder(pipe)
process.Stdout = os.Stdout
//UPDATE: encoder.Encode(&dispreq.DispReq{w, r})
//UPDATE: process.Start()
process.Start()
encoder.Encode(&dispreq.DispReq{w, r})
pipe.Close()
process.Wait()
}
func main() {
http.HandleFunc("/", dispatch)
http.ListenAndServe(":8080", nil)
}
hello.go
package main
import (
"dispreq"
"encoding/gob"
"os"
"fmt"
)
func main() {
gobDecoder := gob.NewDecoder(os.Stdin)
var request dispreq.DispReq
gobDecoder.Decode(&request)
fmt.Fprintf(request.Resp, "Hello")
}
You should start the process (process.Start()
) before sending data to it (encoder.Encode(&dispreq.DispReq{w, r})
). You might also need to flush your pipe by closing it (pipe.Close()
) or sending a \n
.