@@ -37,6 +37,7 @@ type taskHandle struct {
37
37
stats * common.TaskStatistics
38
38
39
39
driverConfig * common.MySQLDriverConfig
40
+ shutdown bool
40
41
}
41
42
42
43
func newDtleTaskHandle (logger g.LoggerType , cfg * drivers.TaskConfig , state drivers.TaskState , started time.Time ) * taskHandle {
@@ -51,9 +52,21 @@ func newDtleTaskHandle(logger g.LoggerType, cfg *drivers.TaskConfig, state drive
51
52
waitCh : make (chan * drivers.ExitResult ),
52
53
doneCh : make (chan struct {}),
53
54
}
55
+ go h .watchWaitCh ()
54
56
return h
55
57
}
56
58
59
+ func (h * taskHandle ) watchWaitCh () {
60
+ select {
61
+ case r := <- h .waitCh :
62
+ h .stateLock .Lock ()
63
+ h .exitResult = r
64
+ h .stateLock .Unlock ()
65
+ close (h .doneCh )
66
+ case <- h .doneCh :
67
+ }
68
+ }
69
+
57
70
func (h * taskHandle ) TaskStatus () (* drivers.TaskStatus , error ) {
58
71
h .stateLock .RLock ()
59
72
defer h .stateLock .RUnlock ()
@@ -81,13 +94,14 @@ func (h *taskHandle) TaskStatus() (*drivers.TaskStatus, error) {
81
94
}, nil
82
95
}
83
96
97
+ // used when h.runner has not been setup
84
98
func (h * taskHandle ) onError (err error ) {
85
- h .waitCh <- & drivers.ExitResult {
99
+ common . WriteWaitCh ( h .waitCh , & drivers.ExitResult {
86
100
ExitCode : common .TaskStateDead ,
87
101
Signal : 0 ,
88
102
OOMKilled : false ,
89
103
Err : err ,
90
- }
104
+ })
91
105
}
92
106
93
107
func (h * taskHandle ) IsRunning () bool {
@@ -136,7 +150,7 @@ func (h *taskHandle) run(d *Driver) {
136
150
for {
137
151
select {
138
152
case <- h .doneCh :
139
- t .Stop ()
153
+ if ! t .Stop () { <- t . C }
140
154
return
141
155
case <- t .C :
142
156
if h .runner != nil {
@@ -264,26 +278,35 @@ func (h *taskHandle) emitStats(ru *common.TaskStatistics) {
264
278
}
265
279
}
266
280
267
- func (h * taskHandle ) Destroy () bool {
268
- h .stateLock .RLock ()
269
- defer h .stateLock .RUnlock ()
281
+ func (h * taskHandle ) Destroy () {
282
+ if h .shutdown {
283
+ return
284
+ }
285
+ h .stateLock .Lock ()
286
+ h .shutdown = true
287
+ h .stateLock .Unlock ()
270
288
271
- close (h .doneCh )
289
+ common .WriteWaitCh (h .waitCh , & drivers.ExitResult {
290
+ ExitCode : 0 ,
291
+ Signal : 0 ,
292
+ OOMKilled : false ,
293
+ Err : nil ,
294
+ })
272
295
273
296
if h .runner != nil {
274
297
err := h .runner .Shutdown ()
275
298
if err != nil {
276
299
h .logger .Error ("error in h.runner.Shutdown" , "err" , err )
277
300
}
278
301
}
279
-
280
- return h .procState == drivers .TaskStateExited
281
302
}
282
303
283
304
type DriverHandle interface {
284
305
Run ()
285
306
286
- // Shutdown is used to stop the task
307
+ // Shutdown is used to stop the task.
308
+ // Do not send ExitResult in Shutdown().
309
+ // pause API will call Shutdown and the task should not exit.
287
310
Shutdown () error
288
311
289
312
// Stats returns aggregated stats of the driver
0 commit comments