fix(daemon): keep systemd gateway running after child OOM (#93585)

Co-authored-by: snowzlm <snowzlm@noreply.codeberg.org>
This commit is contained in:
snowzlm 2026-06-23 02:54:21 +08:00 committed by GitHub
parent f8df80646b
commit 10113b2c9f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 12 additions and 0 deletions

View file

@ -259,6 +259,7 @@ RestartSec=5
TimeoutStopSec=30
TimeoutStartSec=30
SuccessExitStatus=0 143
OOMPolicy=continue
KillMode=control-group
[Install]

View file

@ -86,6 +86,7 @@ RestartSec=5
TimeoutStopSec=30
TimeoutStartSec=30
SuccessExitStatus=0 143
OOMPolicy=continue
KillMode=control-group
[Install]
@ -130,6 +131,11 @@ cat /proc/<child-pid>/oom_score_adj
Expected value for covered children is `1000`. The Gateway process should keep
its normal score, usually `0`.
The recommended systemd unit also sets `OOMPolicy=continue`. This keeps the
Gateway unit alive when a transient child process is selected by the OOM killer;
the child command/session can fail and report its error without systemd marking
the entire gateway service failed and restarting all channels.
This does not replace normal memory tuning. If a VPS or container repeatedly
kills children, increase the memory limit, reduce concurrency, or add stronger
resource controls such as systemd `MemoryMax=` or container-level memory limits.

View file

@ -23,6 +23,7 @@ describe("buildSystemdUnit", () => {
expect(unit).toContain("TimeoutStopSec=30");
expect(unit).toContain("TimeoutStartSec=30");
expect(unit).toContain("SuccessExitStatus=0 143");
expect(unit).toContain("OOMPolicy=continue");
expect(unit).toContain("StartLimitBurst=5");
expect(unit).toContain("StartLimitIntervalSec=60");
expect(unit).toContain("RestartPreventExitStatus=78");

View file

@ -81,6 +81,10 @@ export function buildSystemdUnit({
"TimeoutStopSec=30",
"TimeoutStartSec=30",
"SuccessExitStatus=0 143",
// Transient child processes may be selected by the OOM killer before the
// gateway. Keep the service running when that happens; the child surface is
// already responsible for reporting the failed command/session.
"OOMPolicy=continue",
// Keep service children in the same lifecycle so restarts do not leave
// orphan ACP/runtime workers behind.
"KillMode=control-group",