AppRunner: Build next version in the background to reduce downtime
Next step would be to make this point of transition configurable.
Change-Id: Ibf6504a02b2d1c376e70e944e1aaada0f2dea589
diff --git a/apps/app-runner/server.go b/apps/app-runner/server.go
index ffc5709..1779a76 100644
--- a/apps/app-runner/server.go
+++ b/apps/app-runner/server.go
@@ -29,6 +29,7 @@
self string
managerAddr string
logs *Log
+ currDir string
}
func NewServer(port int, appId string, repoAddr, branch string, signer ssh.Signer, appDir string, runCommands []Command, self string, manager string) *Server {
@@ -45,6 +46,7 @@
self: self,
managerAddr: manager,
logs: &Log{},
+ currDir: "",
}
}
@@ -78,20 +80,6 @@
s.l.Lock()
s.ready = false
s.l.Unlock()
- if s.cmd != nil {
- err := syscall.Kill(-s.cmd.Process.Pid, syscall.SIGKILL)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- // NOTE(gio): No need to check err as we just killed the process
- s.cmd.Wait()
- s.cmd = nil
- }
- if err := os.RemoveAll(s.appDir); err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
if err := s.run(); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -102,7 +90,11 @@
}
func (s *Server) run() error {
- if err := CloneRepositoryBranch(s.repoAddr, s.branch, s.signer, s.appDir); err != nil {
+ newDir, err := os.MkdirTemp(s.appDir, "code-*")
+ if err != nil {
+ return err
+ }
+ if err := CloneRepositoryBranch(s.repoAddr, s.branch, s.signer, newDir); err != nil {
return err
}
logM := io.MultiWriter(os.Stdout, s.logs)
@@ -110,7 +102,7 @@
args := []string{c.Bin}
args = append(args, c.Args...)
cmd := &exec.Cmd{
- Dir: *appDir,
+ Dir: newDir,
Path: c.Bin,
Args: args,
Env: append(os.Environ(), c.Env...),
@@ -124,12 +116,22 @@
return err
}
} else {
+ if s.cmd != nil {
+ // TODO(gio): make this point configurable
+ if err := s.kill(); err != nil {
+ return err
+ }
+ if err := os.RemoveAll(s.currDir); err != nil {
+ return err
+ }
+ }
if err := cmd.Start(); err != nil {
return err
}
s.cmd = cmd
}
}
+ s.currDir = newDir
return nil
}
@@ -155,3 +157,18 @@
registerWorkerAddr := fmt.Sprintf("%s/api/apps/%s/workers", s.managerAddr, s.appId)
http.Post(registerWorkerAddr, "application/json", bytes.NewReader(buf))
}
+
+func (s *Server) kill() error {
+ if s.cmd == nil {
+ return nil
+ }
+
+ err := syscall.Kill(-s.cmd.Process.Pid, syscall.SIGKILL)
+ if err != nil {
+ return err
+ }
+ // NOTE(gio): No need to check err as we just killed the process
+ s.cmd.Wait()
+ s.cmd = nil
+ return nil
+}