Files
gotenberg/internal/pkg/pm2/pm2.go
Nicholas Jones 6846e7941f Install pm2 via npm (#72)
As noted in the Dockerfile, the previous route to install pm2 was broken at
some point. As a result, pm2 related files are now being copied over from an
image created prior to the breakage.

This change now installs pm2 via npm, which is the recommended route for this.
A small adjustment had to be made in the processManager code; an
argument was being passed with a space in it. For reasons that I've not been
able to fully trace, this no longer works. It should be noted that passing
arguments in this way can result in undesirable behaviour - in this case I
believe "--interpreter none" was being passed as a single argument, rather than
"--interpreter", "none". I've adjusted this to use an equals - splitting into 2
separate strings works well too.
2019-05-09 11:15:37 +02:00

84 lines
1.5 KiB
Go

package pm2
import (
"fmt"
"os/exec"
)
const (
stoppedState = iota
runningState
errorState
)
// Process is a type that can start or
// shutdown a process with PM2.
type Process interface {
Fullname() string
Start() error
Shutdown() error
args() []string
name() string
viable() bool
warmup()
}
type processManager struct {
heuristicState int32
}
func (m *processManager) start(p Process) error {
if err := m.pm2(p, "start"); err != nil {
return err
}
p.warmup()
if !p.viable() {
attempts := 0
for attempts < 5 && !p.viable() {
if err := m.pm2(p, "restart"); err != nil {
m.heuristicState = errorState
return err
}
p.warmup()
attempts++
}
if !p.viable() {
m.heuristicState = errorState
return fmt.Errorf("failed to launch %s", p.Fullname())
}
}
m.heuristicState = runningState
return nil
}
func (m *processManager) shutdown(p Process) error {
if m.heuristicState != runningState {
return nil
}
if err := m.pm2(p, "stop"); err != nil {
m.heuristicState = errorState
return err
}
m.heuristicState = stoppedState
return nil
}
func (m *processManager) pm2(p Process, cmdName string) error {
cmdArgs := []string{
cmdName,
p.name(),
}
if cmdName == "start" {
cmdArgs = append(cmdArgs, "--interpreter=none", "--")
cmdArgs = append(cmdArgs, p.args()...)
}
cmd := exec.Command(
"pm2",
cmdArgs...,
)
if err := cmd.Start(); err != nil {
return fmt.Errorf("%s %s with PM2: %v", cmdName, p.Fullname(), err)
}
return nil
}