@@ -57,23 +57,36 @@ func NewWatchdog(restartable bool, restartTimeout time.Duration, logger *ttlog.L
57
57
provider : provider }
58
58
59
59
wd .done = make (chan bool , 1 )
60
- wd .shouldStop = false
61
60
62
61
return & wd
63
62
}
64
63
65
64
// Start starts the Instance and signal handling.
66
- func (wd * Watchdog ) Start () {
65
+ func (wd * Watchdog ) Start (preStartAction func () error ) error {
66
+ var err error
67
+ // Create Instance.
68
+ if wd .Instance , err = wd .provider .CreateInstance (wd .logger ); err != nil {
69
+ wd .logger .Printf (`Watchdog(ERROR): "%v".` , err )
70
+ return err
71
+ }
72
+ wd .logger = wd .Instance .logger
73
+ // The signal handling loop must be started before the instance
74
+ // get started for avoiding a race condition between tt start
75
+ // and tt stop. This way we avoid a situation when we receive
76
+ // a signal before starting a handler for it.
77
+ wd .startSignalHandling ()
78
+
79
+ if err = preStartAction (); err != nil {
80
+ wd .logger .Printf (`Pre-start action error: %v` , err )
81
+ // Finish the signal handling goroutine.
82
+ wd .done <- true
83
+ return err
84
+ }
85
+
67
86
// The Instance must be restarted on completion if the "restartable"
68
87
// parameter is set to "true".
69
88
for {
70
89
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
77
90
78
91
wd .instanceStateMutex .Lock ()
79
92
if ! wd .shouldStop {
@@ -87,7 +100,7 @@ func (wd *Watchdog) Start() {
87
100
} else {
88
101
wd .logger .Printf (`Watchdog(ERROR): terminated before instance start.` )
89
102
wd .instanceStateMutex .Unlock ()
90
- return
103
+ return nil
91
104
}
92
105
wd .instanceStateMutex .Unlock ()
93
106
@@ -125,13 +138,21 @@ func (wd *Watchdog) Start() {
125
138
time .Sleep (wd .restartTimeout )
126
139
127
140
wd .shouldStop = false
141
+
142
+ // Create Instance.
143
+ if wd .Instance , err = wd .provider .CreateInstance (wd .logger ); err != nil {
144
+ wd .logger .Printf (`Watchdog(ERROR): "%v".` , err )
145
+ return err
146
+ }
147
+ wd .logger = wd .Instance .logger
128
148
// Before the restart of an instance start a new signal handling loop.
129
- wd .StartSignalHandling ()
149
+ wd .startSignalHandling ()
130
150
}
151
+ return nil
131
152
}
132
153
133
- // StartSignalHandling starts signal handling in a separate goroutine.
134
- func (wd * Watchdog ) StartSignalHandling () {
154
+ // startSignalHandling starts signal handling in a separate goroutine.
155
+ func (wd * Watchdog ) startSignalHandling () {
135
156
sigChan := make (chan os.Signal , 1 )
136
157
// Reset the signal mask before starting of the new loop.
137
158
signal .Reset ()
0 commit comments