Skip to content

Commit bf22d6f

Browse files
committed
feat(main): ignoring SIGTERM when managed by PM2
- there is a race condition during shutting down when go-judge receives SIGTERM from systemd and PM2 dumps a STOPPED status, resulting go-judge not auto-restart after a reboot - PM2 uses SIGINT for stop signal so that we can distinguish different stop signal sent by different process manager - So when detected that we are manged by PM2, we ignore the SIGTERM signal from the systemd and wait for PM2's SIGINT to avoid race condition Unitech/pm2#6036
1 parent 565f302 commit bf22d6f

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

cmd/go-judge/main.go

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"runtime"
1717
"runtime/debug"
1818
"strings"
19+
"syscall"
1920
"time"
2021

2122
"github.com/criyle/go-judge/cmd/go-judge/config"
@@ -106,9 +107,21 @@ func main() {
106107
newForceGCWorker(conf)
107108

108109
// Graceful shutdown...
109-
signal.Notify(sig, os.Interrupt)
110-
<-sig
111-
signal.Reset(os.Interrupt)
110+
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
111+
loop:
112+
for s := range sig {
113+
switch s {
114+
case syscall.SIGINT:
115+
break loop
116+
case syscall.SIGTERM:
117+
if isManagedByPM2() {
118+
logger.Info("running with PM2, received SIGTERM (from systemd), ignoring")
119+
} else {
120+
break loop
121+
}
122+
}
123+
}
124+
signal.Reset(syscall.SIGINT, syscall.SIGTERM)
112125

113126
logger.Info("Shutting Down...")
114127

@@ -591,3 +604,18 @@ func generateHandleConfig(conf *config.Config, builderParam map[string]any) func
591604
})
592605
}
593606
}
607+
608+
func isManagedByPM2() bool {
609+
// List of environment variables that pm2 typically sets.
610+
pm2EnvVars := []string{
611+
"PM2_HOME",
612+
"PM2_JSON_PROCESSING",
613+
"NODE_APP_INSTANCE",
614+
}
615+
for _, v := range pm2EnvVars {
616+
if os.Getenv(v) != "" {
617+
return true
618+
}
619+
}
620+
return false
621+
}

env/env_cgroup_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func startTransientUnit(conn *dbus.Conn, scopeName string, logger *zap.Logger) e
7676
dbus.PropWants(scopeName),
7777
dbus.PropPids(uint32(os.Getpid())),
7878
newSystemdProperty("Delegate", true),
79+
newSystemdProperty("KillMode", "process"),
7980
}
8081
ch := make(chan string, 1)
8182
if _, err := conn.StartTransientUnitContext(context.TODO(), scopeName, "replace", properties, ch); err != nil {

0 commit comments

Comments
 (0)