@@ -17,6 +17,7 @@ package apitest
17
17
import (
18
18
"context"
19
19
"fmt"
20
+ "sync"
20
21
21
22
"github.com/sirupsen/logrus"
22
23
@@ -30,9 +31,10 @@ import (
30
31
var Kind = types .Kind (spec .PipelineTaskExecutorKindAPITest )
31
32
32
33
type define struct {
33
- name types.Name
34
- options map [string ]string
35
- dbClient * dbclient.Client
34
+ name types.Name
35
+ options map [string ]string
36
+ dbClient * dbclient.Client
37
+ runningApis sync.Map
36
38
}
37
39
38
40
func (d * define ) Kind () types.Kind { return Kind }
@@ -46,7 +48,11 @@ func (d *define) Exist(ctx context.Context, task *spec.PipelineTask) (created bo
46
48
case status == apistructs .PipelineStatusCreated :
47
49
return true , false , nil
48
50
case status == apistructs .PipelineStatusQueue , status == apistructs .PipelineStatusRunning :
49
- return true , true , nil
51
+ // if apitest task is not procesing, should make status-started false
52
+ if _ , alreadyProcessing := d .runningApis .Load (d .makeRunningApiKey (task )); alreadyProcessing {
53
+ return true , true , nil
54
+ }
55
+ return true , false , nil
50
56
case status .IsEndStatus ():
51
57
return true , true , nil
52
58
default :
@@ -61,6 +67,10 @@ func (d *define) Create(ctx context.Context, task *spec.PipelineTask) (interface
61
67
func (d * define ) Start (ctx context.Context , task * spec.PipelineTask ) (interface {}, error ) {
62
68
63
69
go func (ctx context.Context , task * spec.PipelineTask ) {
70
+ if _ , alreadyProcessing := d .runningApis .LoadOrStore (d .makeRunningApiKey (task ), task ); alreadyProcessing {
71
+ logrus .Warnf ("apitest: task: %d already processing" , task .ID )
72
+ return
73
+ }
64
74
executorDoneCh , ok := ctx .Value (spec .MakeTaskExecutorCtxKey (task )).(chan interface {})
65
75
if ! ok {
66
76
logrus .Warnf ("apitest: failed to get executor channel, pipelineID: %d, taskID: %d" , task .PipelineID , task .ID )
@@ -75,6 +85,7 @@ func (d *define) Start(ctx context.Context, task *spec.PipelineTask) (interface{
75
85
if executorDoneCh != nil {
76
86
executorDoneCh <- apistructs.PipelineStatusDesc {Status : status }
77
87
}
88
+ d .runningApis .Delete (d .makeRunningApiKey (task ))
78
89
}()
79
90
80
91
logic .Do (ctx , task )
@@ -112,7 +123,7 @@ func (d *define) Status(ctx context.Context, task *spec.PipelineTask) (apistruct
112
123
return apistructs.PipelineStatusDesc {Status : task .Status }, nil
113
124
}
114
125
115
- created , _ , err := d .Exist (ctx , task )
126
+ created , started , err := d .Exist (ctx , task )
116
127
if err != nil {
117
128
return apistructs.PipelineStatusDesc {}, err
118
129
}
@@ -121,6 +132,10 @@ func (d *define) Status(ctx context.Context, task *spec.PipelineTask) (apistruct
121
132
return apistructs.PipelineStatusDesc {Status : apistructs .PipelineStatusAnalyzed }, nil
122
133
}
123
134
135
+ if ! started && len (latestTask .Result .Metadata ) == 0 {
136
+ return apistructs.PipelineStatusDesc {Status : apistructs .PipelineStatusBorn }, nil
137
+ }
138
+
124
139
// status according to api success or not
125
140
meta := latestTask .Result .Metadata
126
141
for _ , metaField := range meta {
@@ -154,16 +169,21 @@ func (d *define) BatchDelete(ctx context.Context, actions []*spec.PipelineTask)
154
169
return nil , nil
155
170
}
156
171
172
+ func (d * define ) makeRunningApiKey (task * spec.PipelineTask ) string {
173
+ return fmt .Sprintf ("%d-%d" , task .PipelineID , task .ID )
174
+ }
175
+
157
176
func init () {
158
177
types .MustRegister (Kind , func (name types.Name , options map [string ]string ) (types.ActionExecutor , error ) {
159
178
dbClient , err := dbclient .New ()
160
179
if err != nil {
161
180
return nil , fmt .Errorf ("failed to init dbclient, err: %v" , err )
162
181
}
163
182
return & define {
164
- name : name ,
165
- options : options ,
166
- dbClient : dbClient ,
183
+ name : name ,
184
+ options : options ,
185
+ dbClient : dbClient ,
186
+ runningApis : sync.Map {},
167
187
}, nil
168
188
})
169
189
}
0 commit comments