【发布时间】:2021-06-30 21:03:11
【问题描述】:
我使用go-daemon 库来分叉进程并在后台运行它。而且我需要在从 http 处理程序中执行更新后重新启动守护进程。
处理程序代码是
func httpUpdate(w http.ResponseWriter, req *http.Request) {
if !isPost(req.Method) {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
if checkAuth(req) != 200 {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
log.Println("INFO: Update request, checking for update...")
var err = doUpdate(UPDATE_URL, nil, false)
if !isError(err) {
log.Println("INFO: Update successful, exit")
var system = RealSystem{}
system.Run(fmt.Sprintf("(sleep 0.3s && %s start &> /test/extra.log)&disown", appFilename()))
system.Exit(0)
return
}
w.WriteHeader(http.StatusNoContent)
}
doUpdate() 如果成功替换了可执行文件,则返回nil。 RealSystem 只是 exec.Command 和 os.Exit() 的包装。 appFilename() 是可执行文件名。启动应用的命令是/path/to/app start。
我看到新进程启动了,但执行 Context::Reborn() 失败并出现 EOF 错误。看起来一些用作实现细节的内在管道因EOF 而失败(可能是......)。
原因是什么?或者可能有更好的方法吗?
现在一切都发生在 docker 容器内的 e2e 测试的“上下文”中,如果重要的话。我花了几个小时试图让它工作,但没有成功。
【问题讨论】: