Files
gotenberg/internal/pkg/pm2/pm2.go
Julien Neuhart 7bfbda4490 huge refactoring
2019-07-23 13:57:18 +02:00

103 lines
2.3 KiB
Go

package pm2
import (
"fmt"
"github.com/thecodingmachine/gotenberg/internal/pkg/xerror"
"github.com/thecodingmachine/gotenberg/internal/pkg/xexec"
"github.com/thecodingmachine/gotenberg/internal/pkg/xlog"
)
// Process is a type that can start or
// stop a process with PM2.
type Process interface {
Fullname() string
Start() error
IsViable() bool
Stop() error
args() []string
binary() string
warmup()
}
type pm2Command string
const (
startCommand pm2Command = "start"
restartCommand pm2Command = "restart"
stopCommand pm2Command = "stop"
logsCommand pm2Command = "logs"
)
func start(logger xlog.Logger, process Process) error {
const (
op string = "pm2.start"
maximumAttempts int = 3
)
resolver := func() error {
// first, we try to start the process.
if err := run(logger, startCommand, process); err != nil {
return err
}
// we wait the process to be ready.
process.warmup()
// if the process failed to start correctly,
// we have to restart it.
if !process.IsViable() {
attempts := 0
for attempts < maximumAttempts && !process.IsViable() {
if err := run(logger, restartCommand, process); err != nil {
return err
}
process.warmup()
attempts++
}
if !process.IsViable() {
return fmt.Errorf("failed to start '%s'", process.Fullname())
}
}
// the process is viable, let's log its
// output.
if err := run(logger, logsCommand, process); err != nil {
return err
}
return nil
}
if err := resolver(); err != nil {
return xerror.New(op, err)
}
return nil
}
func stop(logger xlog.Logger, process Process) error {
const op string = "pm2.stop"
if err := run(logger, stopCommand, process); err != nil {
return xerror.New(op, err)
}
return nil
}
func run(logger xlog.Logger, pm2Cmd pm2Command, process Process) error {
const op string = "pm2.run"
resolver := func() error {
args := []string{
string(pm2Cmd),
process.binary(),
}
if pm2Cmd == startCommand {
args = append(args, "--interpreter=none", "--")
args = append(args, process.args()...)
}
cmd, err := xexec.Command(logger, "pm2", args...)
if err != nil {
return err
}
xexec.LogBeforeExecute(logger, cmd)
return cmd.Start()
}
if err := resolver(); err != nil {
return xerror.New(op, err)
}
return nil
}