Skip to content

Commit

Permalink
Process: Add timeout and force killing for process deletion
Browse files Browse the repository at this point in the history
Longhorn 8091

Signed-off-by: Shuo Wu <shuo.wu@suse.com>
  • Loading branch information
shuo-wu committed Mar 25, 2024
1 parent 3dc3e81 commit 59ab5d6
Showing 1 changed file with 33 additions and 16 deletions.
49 changes: 33 additions & 16 deletions pkg/process/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,22 @@ const (
StateError = State(types.ProcessStateError)
)

const DeleteTimeout = 30 * time.Second

type Process struct {
Name string
Binary string
Args []string
PortCount int32
PortArgs []string

UUID string
State State
ErrorMsg string
Conditions map[string]bool
PortStart int32
PortEnd int32
UUID string
State State
ErrorMsg string
Conditions map[string]bool
PortStart int32
PortEnd int32
DeletionTimestamp *time.Time

lock *sync.RWMutex
cmd Command
Expand Down Expand Up @@ -137,15 +140,25 @@ func (p *Process) Stop() {
}

func (p *Process) StopWithSignal(signal syscall.Signal) {
needStop := false
needStop, needTimeoutKill := false, false
now := time.Now()

p.lock.Lock()
if p.State != StateStopping && p.State != StateStopped && p.State != StateError {
p.State = StateStopping
p.DeletionTimestamp = &now
needStop = true
}
// Retry the deletion if the process is not stopped in 30 seconds
if p.DeletionTimestamp != nil && !needStop {
if p.DeletionTimestamp.Add(DeleteTimeout).After(now) {
logrus.Infof("Process Manager: process %v deletion takes more than %vs, will retry it", p.Name, DeleteTimeout.Seconds())
needTimeoutKill = true
}
}
p.lock.Unlock()

if !needStop {
if !needStop && !needTimeoutKill {
return
}
p.UpdateCh <- p
Expand All @@ -170,16 +183,20 @@ func (p *Process) StopWithSignal(signal syscall.Signal) {
}

// no need for lock
logrus.Infof("Process Manager: trying to stop process %v", p.Name)
cmd.StopWithSignal(signal)
for i := 0; i < types.WaitCount; i++ {
if p.IsStopped() {
return
if needStop {
logrus.Infof("Process Manager: trying to stop process %v", p.Name)
cmd.StopWithSignal(signal)
for i := 0; i < types.WaitCount; i++ {
if p.IsStopped() {
return
}
logrus.Infof("Wait for process %v to shutdown", p.Name)
time.Sleep(types.WaitInterval)
}
logrus.Infof("Wait for process %v to shutdown", p.Name)
time.Sleep(types.WaitInterval)
logrus.Warnf("Process Manager: cannot graceful stop process %v in %v, will kill the process", p.Name, time.Duration(types.WaitCount)*types.WaitInterval)
} else if needTimeoutKill {
logrus.Warnf("Process Manager: somehow timeout stopping process %v, will retry killing the process", p.Name)
}
logrus.Warnf("Process Manager: cannot graceful stop process %v in %v, will kill the process", p.Name, time.Duration(types.WaitCount)*types.WaitInterval)
cmd.Kill()
}()
}
Expand Down

0 comments on commit 59ab5d6

Please sign in to comment.