Skip to content

Commit ea4ad6d

Browse files
committed
TO SQUASH OR REMOVE
1 parent 97ec3cc commit ea4ad6d

File tree

3 files changed

+56
-47
lines changed

3 files changed

+56
-47
lines changed

cli/running/running.go

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -518,21 +518,17 @@ func Start(cmdCtx *cmdcontext.CmdCtx, run *InstanceCtx) error {
518518
provider := providerImpl{cmdCtx: cmdCtx, instanceCtx: run}
519519
wd := NewWatchdog(run.Restartable, 5*time.Second, logger, &provider)
520520

521-
// The signal handling loop must be started before the instance
522-
// get started for avoiding a race condition between tt start
523-
// and tt stop. This way we avoid a situation when we receive
524-
// a signal before starting a handler for it.
525-
wd.StartSignalHandling()
526-
527-
if err := process_utils.CreatePIDFile(run.PIDFile); err != nil {
528-
return err
529-
}
530-
531521
defer func() {
532522
cleanup(run)
533523
}()
534524

535-
wd.Start()
525+
preStartAction := func() error {
526+
if err := process_utils.CreatePIDFile(run.PIDFile); err != nil {
527+
return err
528+
}
529+
return nil
530+
}
531+
wd.Start(preStartAction)
536532
return nil
537533
}
538534

cli/running/watchdog.go

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@ type Watchdog struct {
4444
provider Provider
4545
// instanceStateMutex used to avoid a race condition under started and shouldStop fields.
4646
instanceStateMutex sync.Mutex
47-
// started indicates whether the Watchdog has started an Instance.
48-
started bool
49-
// shouldStop indicates whether the Watchdog should stop the Instance.
47+
// shouldStop indicates whether the Watchdog should be stopped.
5048
shouldStop bool
5149
}
5250

@@ -57,37 +55,48 @@ func NewWatchdog(restartable bool, restartTimeout time.Duration, logger *ttlog.L
5755
provider: provider}
5856

5957
wd.done = make(chan bool, 1)
60-
wd.shouldStop = false
6158

6259
return &wd
6360
}
6461

6562
// Start starts the Instance and signal handling.
66-
func (wd *Watchdog) Start() {
63+
func (wd *Watchdog) Start(preStartAction func() error) error {
64+
var err error
65+
// Create Instance.
66+
if wd.Instance, err = wd.provider.CreateInstance(wd.logger); err != nil {
67+
wd.logger.Printf(`Watchdog(ERROR): "%v".`, err)
68+
return err
69+
}
70+
wd.logger = wd.Instance.logger
71+
// The signal handling loop must be started before the instance
72+
// get started for avoiding a race condition between tt start
73+
// and tt stop. This way we avoid a situation when we receive
74+
// a signal before starting a handler for it.
75+
wd.startSignalHandling()
76+
77+
if err = preStartAction(); err != nil {
78+
wd.logger.Printf(`Pre-start action error: %v`, err)
79+
// Finish the signal handling goroutine.
80+
wd.done <- true
81+
return err
82+
}
83+
6784
// The Instance must be restarted on completion if the "restartable"
6885
// parameter is set to "true".
6986
for {
7087
var err error
71-
// Create Instance.
72-
if wd.Instance, err = wd.provider.CreateInstance(wd.logger); err != nil {
73-
wd.logger.Printf(`Watchdog(ERROR): "%v".`, err)
74-
break
75-
}
76-
wd.logger = wd.Instance.logger
7788

7889
wd.instanceStateMutex.Lock()
79-
if !wd.shouldStop {
80-
// Start the Instance.
81-
if err := wd.Instance.Start(); err != nil {
82-
wd.logger.Printf(`Watchdog(ERROR): "%v".`, err)
83-
wd.instanceStateMutex.Unlock()
84-
break
85-
}
86-
wd.started = true
87-
} else {
90+
if wd.shouldStop {
8891
wd.logger.Printf(`Watchdog(ERROR): terminated before instance start.`)
8992
wd.instanceStateMutex.Unlock()
90-
return
93+
return nil
94+
}
95+
// Start the Instance.
96+
if err := wd.Instance.Start(); err != nil {
97+
wd.logger.Printf(`Watchdog(ERROR): "%v".`, err)
98+
wd.instanceStateMutex.Unlock()
99+
break
91100
}
92101
wd.instanceStateMutex.Unlock()
93102

@@ -96,10 +105,6 @@ func (wd *Watchdog) Start() {
96105
wd.logger.Printf(`Watchdog(WARN): "%v".`, err)
97106
}
98107

99-
wd.instanceStateMutex.Lock()
100-
wd.started = false
101-
wd.instanceStateMutex.Unlock()
102-
103108
// Set Instance process completion indication.
104109
wd.done <- true
105110
// Wait for the signal processing goroutine to complete.
@@ -125,13 +130,21 @@ func (wd *Watchdog) Start() {
125130
time.Sleep(wd.restartTimeout)
126131

127132
wd.shouldStop = false
133+
134+
// Create Instance.
135+
if wd.Instance, err = wd.provider.CreateInstance(wd.logger); err != nil {
136+
wd.logger.Printf(`Watchdog(ERROR): "%v".`, err)
137+
return err
138+
}
139+
wd.logger = wd.Instance.logger
128140
// Before the restart of an instance start a new signal handling loop.
129-
wd.StartSignalHandling()
141+
wd.startSignalHandling()
130142
}
143+
return nil
131144
}
132145

133-
// StartSignalHandling starts signal handling in a separate goroutine.
134-
func (wd *Watchdog) StartSignalHandling() {
146+
// startSignalHandling starts signal handling in a separate goroutine.
147+
func (wd *Watchdog) startSignalHandling() {
135148
sigChan := make(chan os.Signal, 1)
136149
// Reset the signal mask before starting of the new loop.
137150
signal.Reset()
@@ -158,22 +171,20 @@ func (wd *Watchdog) StartSignalHandling() {
158171
switch sig {
159172
case syscall.SIGINT, syscall.SIGTERM:
160173
wd.instanceStateMutex.Lock()
161-
if wd.started {
162-
wd.Instance.Stop(30 * time.Second)
163-
}
164174
// If we receive one of the "stop" signals, the
165175
// program should be terminated.
166176
wd.shouldStop = true
167177
wd.instanceStateMutex.Unlock()
178+
if wd.Instance.IsAlive() {
179+
wd.Instance.Stop(30 * time.Second)
180+
}
168181
case syscall.SIGHUP:
169182
// Rotate the log files.
170183
wd.logger.Rotate()
171184
default:
172-
wd.instanceStateMutex.Lock()
173-
if wd.started {
185+
if wd.Instance.IsAlive() {
174186
wd.Instance.SendSignal(sig)
175187
}
176-
wd.instanceStateMutex.Unlock()
177188
}
178189
case _ = <-wd.done:
179190
return

cli/running/watchdog_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,9 @@ func TestWatchdogBase(t *testing.T) {
112112
t.Cleanup(func() { cleanupWatchdog(wd) })
113113

114114
wdDoneChan := make(chan bool, 1)
115+
testPreAction := func() error { return nil }
115116
go func() {
116-
wd.Start()
117+
wd.Start(testPreAction)
117118
wdDoneChan <- true
118119
}()
119120
waitProcessStart()
@@ -140,8 +141,9 @@ func TestWatchdogNotRestartable(t *testing.T) {
140141
t.Cleanup(func() { cleanupWatchdog(wd) })
141142

142143
wdDoneChan := make(chan bool, 1)
144+
testPreAction := func() error { return nil }
143145
go func() {
144-
wd.Start()
146+
wd.Start(testPreAction)
145147
wdDoneChan <- true
146148
}()
147149
waitProcessStart()

0 commit comments

Comments
 (0)