mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-09 00:52:14 +01:00
103 lines
2.3 KiB
Go
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
|
|
}
|