Skip to content

Commit 424a20a

Browse files
author
David Grieser
committed
Fix ai.
1 parent 6b91bb6 commit 424a20a

File tree

5 files changed

+34
-283
lines changed

5 files changed

+34
-283
lines changed

pkg/proc/basejob.go

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,14 @@ func (job *baseJob) SignalAll(sig syscall.Signal) {
3939
}
4040

4141
log.WithField("job.name", job.Config.Name).Infof("sending signal %d to process group", sig)
42-
// job.Cmd.Process.Pid is passed; SignalAllFunc is expected to negate it for group signaling if needed.
43-
errFunc(job.SignalAllFunc(job.Cmd.Process.Pid, sig))
42+
errFunc(job.signalAll(sig))
43+
}
44+
45+
func (job *baseJob) signalAll(sig syscall.Signal) error {
46+
if job.Cmd.Process.Pid <= 0 { // Ensure PID is positive before negating
47+
return syscall.Errno(syscall.ESRCH) // No such process or invalid PID
48+
}
49+
return syscall.Kill(-job.Cmd.Process.Pid, sig)
4450
}
4551

4652
func (job *baseJob) Signal(sig os.Signal) {
@@ -59,10 +65,18 @@ func (job *baseJob) Signal(sig os.Signal) {
5965

6066
log.WithField("job.name", job.Config.Name).Infof("sending signal %d to process", sig)
6167
errFunc(
62-
job.SignalFunc(job.Cmd.Process.Pid, sig),
68+
job.signal(sig),
6369
)
6470
}
6571

72+
func (job *baseJob) signal(sig os.Signal) error {
73+
process, err := os.FindProcess(job.Cmd.Process.Pid)
74+
if err != nil {
75+
return err
76+
}
77+
return process.Signal(sig)
78+
}
79+
6680
func (job *baseJob) Reset() {
6781
job.phase = JobPhase{}
6882
}
@@ -170,12 +184,11 @@ func (job *baseJob) startOnce(ctx context.Context, process chan<- *os.Process) e
170184
// job errChan or failed
171185
case err := <-errChan:
172186
if job.Cmd != nil && job.Cmd.Process != nil { // Check if process actually started
173-
// Use SignalAllFunc for consistency. It expects PID and will negate for group.
174-
if termErr := job.SignalAllFunc(job.Cmd.Process.Pid, syscall.SIGTERM); termErr != nil {
187+
if termErr := job.signalAll(syscall.SIGTERM); termErr != nil {
175188
if e, ok := termErr.(syscall.Errno); ok && e == syscall.ESRCH {
176189
// ESRCH (Error No Such Process) is fine, means process group already gone
177190
} else {
178-
l.WithError(termErr).Error("failed to send SIGTERM to job's process group via SignalAllFunc")
191+
l.WithError(termErr).Error("failed to send SIGTERM to job's process group")
179192
}
180193
}
181194
}
@@ -198,15 +211,14 @@ func (job *baseJob) startOnce(ctx context.Context, process chan<- *os.Process) e
198211
case <-ctx.Done():
199212
if job.Cmd != nil && job.Cmd.Process != nil { // Check if process actually started
200213
// ctx canceled, try to terminate job
201-
// Use SignalAllFunc for consistency. It expects PID and will negate for group.
202-
_ = job.SignalAllFunc(job.Cmd.Process.Pid, syscall.SIGTERM)
203-
l.WithField("job.name", job.Config.Name).Info("sent SIGTERM to job's process group via SignalAllFunc on ctx.Done")
214+
_ = job.signalAll(syscall.SIGTERM)
215+
l.WithField("job.name", job.Config.Name).Info("sent SIGTERM to job's process group on ctx.Done")
204216

205217
select {
206218
case <-time.After(time.Second * ShutdownWaitingTimeSeconds):
207219
// process seems to hang, kill process
208-
_ = job.SignalAllFunc(job.Cmd.Process.Pid, syscall.SIGKILL) // Use func for consistency
209-
l.WithField("job.name", job.Config.Name).Error("forcefully killed job via SignalAllFunc")
220+
_ = job.signalAll(syscall.SIGKILL) // Use func for consistency
221+
l.WithField("job.name", job.Config.Name).Error("forcefully killed job")
210222
return nil
211223

212224
case err := <-errChan:
@@ -219,11 +231,6 @@ func (job *baseJob) startOnce(ctx context.Context, process chan<- *os.Process) e
219231
return ctx.Err() // Return context error
220232
}
221233
}
222-
// all good
223-
return err
224-
}
225-
}
226-
}
227234

228235
func (job *baseJob) closeStdFiles() {
229236
hasStdout := len(job.Config.Stdout) > 0

pkg/proc/job_common.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,7 @@ func (job *CommonJob) IsRunning() bool {
180180
if job.Cmd == nil || job.Cmd.Process == nil || job.Cmd.Process.Pid <= 0 {
181181
return false
182182
}
183-
// Use job.SignalFunc with syscall.Signal(0) for process existence check.
184-
// This respects the mockable function. A nil signal (0) is conventional for checking existence.
185-
err := job.SignalFunc(job.Cmd.Process.Pid, syscall.Signal(0))
183+
err := job.signal(syscall.Signal(0))
186184
return err == nil
187185
}
188186

pkg/proc/job_lazy.go

Lines changed: 6 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,46 +10,7 @@ import (
1010
log "github.com/sirupsen/logrus"
1111
)
1212

13-
// LazyJobReapGracePeriod defines the time to wait after SIGTERM before sending SIGKILL.
14-
// It's a variable to allow modification for testing.
15-
var LazyJobReapGracePeriod = 10 * time.Second
16-
17-
// GetLazyJobReapGracePeriodForTest returns the current grace period. Used by tests.
18-
func GetLazyJobReapGracePeriodForTest() time.Duration {
19-
return LazyJobReapGracePeriod
20-
}
21-
22-
// SetCoolDownTimeout allows tests to set a custom coolDownTimeout.
23-
func (job *LazyJob) SetCoolDownTimeout(d time.Duration) {
24-
job.coolDownTimeout = d
25-
}
26-
27-
// SetActiveConnections allows tests to set activeConnections.
28-
func (job *LazyJob) SetActiveConnections(n uint32) {
29-
job.activeConnections = n
30-
}
31-
32-
// SetLastConnectionClosed allows tests to set lastConnectionClosed.
33-
func (job *LazyJob) SetLastConnectionClosed(t time.Time) {
34-
job.lastConnectionClosed = t
35-
}
36-
37-
// SetProcess allows tests to set the job's process.
38-
// This is primarily for simulating a running process.
39-
// It sets both job.process (used by LazyJob specific logic)
40-
// and job.Cmd.Process (used by BaseJob signal methods via job.Cmd).
41-
func (job *LazyJob) SetProcess(p *os.Process) {
42-
job.process = p
43-
if job.Cmd != nil { // Ensure Cmd is initialized
44-
job.Cmd.Process = p
45-
} else if p != nil { // If Cmd is nil, but we have a process, create a dummy Cmd
46-
// This case is tricky; ideally Cmd should be fully set up by a Start-like method.
47-
// For testing reaper logic which relies on job.Cmd.Process.Pid, we need it.
48-
// This might need refinement depending on how tests set up job.Cmd.
49-
// log.Warn("SetProcess called on LazyJob with nil Cmd; creating a minimal Cmd. May need attention.")
50-
// job.Cmd = &exec.Cmd{} // This alone is not enough, Path and SysProcAttr are needed by reaper's callers
51-
}
52-
}
13+
const lazyJobReapGracePeriod = 10 * time.Second
5314

5415
func (job *LazyJob) AssertStarted(ctx context.Context) error {
5516
l := log.WithField("job.name", job.Config.Name)
@@ -118,15 +79,13 @@ func (job *LazyJob) Run(ctx context.Context, errors chan<- error) error {
11879
}()
11980
}
12081

121-
job.StartProcessReaper(ctx) // Renamed to be exported
82+
job.startProcessReaper(ctx)
12283

12384
log.Infof("holding off starting job %s until first request", job.Config.Name)
12485
return nil
12586
}
12687

127-
// StartProcessReaper starts the goroutine that monitors the lazy job's process
128-
// and terminates it if it's idle for too long.
129-
func (job *LazyJob) StartProcessReaper(ctx context.Context) {
88+
func (job *LazyJob) startProcessReaper(ctx context.Context) {
13089
reaperInterval := job.coolDownTimeout / 2
13190
if reaperInterval < 1*time.Second {
13291
reaperInterval = 1 * time.Second
@@ -174,15 +133,15 @@ func (job *LazyJob) StartProcessReaper(ctx context.Context) {
174133
}
175134
pidToReap := job.Cmd.Process.Pid
176135
l.Infof("sending SIGTERM to idle process PID %d", pidToReap)
177-
if err := job.Signal(syscall.SIGTERM); err != nil {
136+
if err := job.signal(syscall.SIGTERM); err != nil {
178137
l.WithError(err).Warnf("failed to send SIGTERM to PID %d", pidToReap)
179138
job.lazyStartLock.Unlock()
180139
continue
181140
}
182141

183142
job.lazyStartLock.Unlock()
184143

185-
graceTimer := time.NewTimer(LazyJobReapGracePeriod) // Use the variable
144+
graceTimer := time.NewTimer(lazyJobReapGracePeriod)
186145
defer graceTimer.Stop()
187146

188147
select {
@@ -191,7 +150,7 @@ func (job *LazyJob) StartProcessReaper(ctx context.Context) {
191150
// Check if the process we sent SIGTERM to is still running
192151
if job.process != nil && job.Cmd != nil && job.Cmd.Process != nil && job.Cmd.Process.Pid == pidToReap {
193152
l.Warnf("process PID %d did not exit after SIGTERM and grace period; sending SIGKILL", pidToReap)
194-
if err := job.SignalAll(syscall.SIGKILL); err != nil {
153+
if err := job.signalAll(syscall.SIGKILL); err != nil {
195154
l.WithError(err).Errorf("failed to send SIGKILL to PID %d", pidToReap)
196155
}
197156
} else if job.process != nil {

pkg/proc/job_lazy_test.go

Lines changed: 0 additions & 195 deletions
This file was deleted.

0 commit comments

Comments
 (0)