@@ -43,9 +43,11 @@ import (
43
43
"go.temporal.io/api/workflowservice/v1"
44
44
45
45
"go.temporal.io/server/api/adminservice/v1"
46
+ "go.temporal.io/server/common"
46
47
"go.temporal.io/server/common/backoff"
47
48
"go.temporal.io/server/common/dynamicconfig"
48
49
"go.temporal.io/server/common/log"
50
+ "go.temporal.io/server/common/persistence"
49
51
"go.temporal.io/server/common/persistence/sql/sqlplugin/mysql"
50
52
"go.temporal.io/server/common/persistence/sql/sqlplugin/postgresql"
51
53
"go.temporal.io/server/common/persistence/sql/sqlplugin/sqlite"
@@ -190,24 +192,28 @@ func (s *namespaceTestSuite) Test_NamespaceDelete_WithWorkflows() {
190
192
nsID := descResp .GetNamespaceInfo ().GetId ()
191
193
192
194
// Start few workflow executions.
195
+ var executions []* commonpb.WorkflowExecution
193
196
for i := 0 ; i < 100 ; i ++ {
194
- _ , err = s .frontendClient .StartWorkflowExecution (ctx , & workflowservice.StartWorkflowExecutionRequest {
197
+ wid := "wf_id_" + strconv .Itoa (i )
198
+ resp , err := s .frontendClient .StartWorkflowExecution (ctx , & workflowservice.StartWorkflowExecutionRequest {
195
199
RequestId : uuid .New (),
196
200
Namespace : "ns_name_los_angeles" ,
197
- WorkflowId : "wf_id_" + strconv . Itoa ( i ) ,
201
+ WorkflowId : wid ,
198
202
WorkflowType : & commonpb.WorkflowType {Name : "workflowTypeName" },
199
203
TaskQueue : & taskqueuepb.TaskQueue {Name : "taskQueueName" },
200
204
})
201
205
s .NoError (err )
206
+ executions = append (executions , & commonpb.WorkflowExecution {
207
+ WorkflowId : wid ,
208
+ RunId : resp .GetRunId (),
209
+ })
202
210
}
203
211
204
212
// Terminate some workflow executions.
205
- for i := 0 ; i < 30 ; i ++ {
213
+ for _ , execution := range executions [: 30 ] {
206
214
_ , err = s .frontendClient .TerminateWorkflowExecution (ctx , & workflowservice.TerminateWorkflowExecutionRequest {
207
- Namespace : "ns_name_los_angeles" ,
208
- WorkflowExecution : & commonpb.WorkflowExecution {
209
- WorkflowId : "wf_id_" + strconv .Itoa (i ),
210
- },
215
+ Namespace : "ns_name_los_angeles" ,
216
+ WorkflowExecution : execution ,
211
217
})
212
218
s .NoError (err )
213
219
}
@@ -224,37 +230,123 @@ func (s *namespaceTestSuite) Test_NamespaceDelete_WithWorkflows() {
224
230
s .NoError (err )
225
231
s .Equal (enumspb .NAMESPACE_STATE_DELETED , descResp2 .GetNamespaceInfo ().GetState ())
226
232
227
- namespaceExistsOp := func () error {
233
+ s . Eventually ( func () bool {
228
234
_ , err := s .frontendClient .DescribeNamespace (ctx , & workflowservice.DescribeNamespaceRequest {
229
235
Id : nsID ,
230
236
})
231
237
var notFound * serviceerror.NamespaceNotFound
232
- if errors .As (err , & notFound ) {
233
- _ , err0 := s .frontendClient .DescribeWorkflowExecution (ctx , & workflowservice.DescribeWorkflowExecutionRequest {
234
- Namespace : "ns_name_los_angeles" ,
235
- Execution : & commonpb.WorkflowExecution {
236
- WorkflowId : "wf_id_0" ,
237
- },
238
- })
239
- _ , err99 := s .frontendClient .DescribeWorkflowExecution (ctx , & workflowservice.DescribeWorkflowExecutionRequest {
238
+ if ! errors .As (err , & notFound ) {
239
+ return false // namespace still exists
240
+ }
241
+
242
+ for _ , execution := range executions {
243
+ _ , err = s .frontendClient .DescribeWorkflowExecution (ctx , & workflowservice.DescribeWorkflowExecutionRequest {
240
244
Namespace : "ns_name_los_angeles" ,
241
245
Execution : & commonpb.WorkflowExecution {
242
- WorkflowId : "wf_id_99" ,
246
+ WorkflowId : execution . GetWorkflowId () ,
243
247
},
244
248
})
245
- if errors .As (err0 , & notFound ) && errors . As ( err99 , & notFound ) {
246
- return nil
249
+ if ! errors .As (err , & notFound ) {
250
+ return false // should never happen
247
251
}
248
252
}
249
- return errors .New ("namespace still exists" )
253
+ return true
254
+ }, 20 * time .Second , time .Second )
255
+ }
256
+
257
+ func (s * namespaceTestSuite ) Test_NamespaceDelete_WithMissingWorkflows () {
258
+ ctx , cancel := rpc .NewContextWithTimeoutAndVersionHeaders (10000 * time .Second )
259
+ defer cancel ()
260
+
261
+ retention := 24 * time .Hour
262
+ _ , err := s .frontendClient .RegisterNamespace (ctx , & workflowservice.RegisterNamespaceRequest {
263
+ Namespace : "ns_name_los_angeles" ,
264
+ Description : "Namespace to delete" ,
265
+ WorkflowExecutionRetentionPeriod : & retention ,
266
+ HistoryArchivalState : enumspb .ARCHIVAL_STATE_DISABLED ,
267
+ VisibilityArchivalState : enumspb .ARCHIVAL_STATE_DISABLED ,
268
+ })
269
+ s .NoError (err )
270
+ // DescribeNamespace reads directly from database but namespace validator uses cache.
271
+ s .cluster .RefreshNamespaceCache ()
272
+
273
+ descResp , err := s .frontendClient .DescribeNamespace (ctx , & workflowservice.DescribeNamespaceRequest {
274
+ Namespace : "ns_name_los_angeles" ,
275
+ })
276
+ s .NoError (err )
277
+ nsID := descResp .GetNamespaceInfo ().GetId ()
278
+
279
+ // Start few workflow executions.
280
+
281
+ var executions []* commonpb.WorkflowExecution
282
+ for i := 0 ; i < 10 ; i ++ {
283
+ wid := "wf_id_" + strconv .Itoa (i )
284
+ resp , err := s .frontendClient .StartWorkflowExecution (ctx , & workflowservice.StartWorkflowExecutionRequest {
285
+ RequestId : uuid .New (),
286
+ Namespace : "ns_name_los_angeles" ,
287
+ WorkflowId : wid ,
288
+ WorkflowType : & commonpb.WorkflowType {Name : "workflowTypeName" },
289
+ TaskQueue : & taskqueuepb.TaskQueue {Name : "taskQueueName" },
290
+ })
291
+ s .NoError (err )
292
+ executions = append (executions , & commonpb.WorkflowExecution {
293
+ WorkflowId : wid ,
294
+ RunId : resp .GetRunId (),
295
+ })
250
296
}
251
297
252
- namespaceExistsPolicy := backoff .NewExponentialRetryPolicy (time .Second ).
253
- WithBackoffCoefficient (1 ).
254
- WithExpirationInterval (30 * time .Second )
298
+ // Delete some workflow executions from DB but not from visibility.
299
+ // Every subsequent delete (from deleteexecutions.Workflow) from ES will take at least 1s due to bulk processor.
300
+ for _ , execution := range executions [0 :5 ] {
301
+ shardID := common .WorkflowIDToHistoryShard (
302
+ nsID ,
303
+ execution .GetWorkflowId (),
304
+ s .clusterConfig .HistoryConfig .NumHistoryShards ,
305
+ )
306
+
307
+ err = s .cluster .GetExecutionManager ().DeleteWorkflowExecution (ctx , & persistence.DeleteWorkflowExecutionRequest {
308
+ ShardID : shardID ,
309
+ NamespaceID : nsID ,
310
+ WorkflowID : execution .GetWorkflowId (),
311
+ RunID : execution .GetRunId (),
312
+ })
313
+ s .NoError (err )
314
+ }
255
315
256
- err = backoff .ThrottleRetry (namespaceExistsOp , namespaceExistsPolicy , func (_ error ) bool { return true })
316
+ delResp , err := s .operatorClient .DeleteNamespace (ctx , & operatorservice.DeleteNamespaceRequest {
317
+ Namespace : "ns_name_los_angeles" ,
318
+ })
319
+ s .NoError (err )
320
+ s .Equal ("ns_name_los_angeles-deleted-" + nsID [:5 ], delResp .GetDeletedNamespace ())
321
+
322
+ descResp2 , err := s .frontendClient .DescribeNamespace (ctx , & workflowservice.DescribeNamespaceRequest {
323
+ Id : nsID ,
324
+ })
257
325
s .NoError (err )
326
+ s .Equal (enumspb .NAMESPACE_STATE_DELETED , descResp2 .GetNamespaceInfo ().GetState ())
327
+
328
+ s .Eventually (func () bool {
329
+ _ , err := s .frontendClient .DescribeNamespace (ctx , & workflowservice.DescribeNamespaceRequest {
330
+ Id : nsID ,
331
+ })
332
+ var notFound * serviceerror.NamespaceNotFound
333
+ if ! errors .As (err , & notFound ) {
334
+ return false // namespace still exists
335
+ }
336
+
337
+ for _ , execution := range executions {
338
+ _ , err = s .frontendClient .DescribeWorkflowExecution (ctx , & workflowservice.DescribeWorkflowExecutionRequest {
339
+ Namespace : "ns_name_los_angeles" ,
340
+ Execution : & commonpb.WorkflowExecution {
341
+ WorkflowId : execution .GetWorkflowId (),
342
+ },
343
+ })
344
+ if ! errors .As (err , & notFound ) {
345
+ return false // should never happen
346
+ }
347
+ }
348
+ return true
349
+ }, 20 * time .Second , time .Second )
258
350
}
259
351
260
352
func (s * namespaceTestSuite ) Test_NamespaceDelete_CrossNamespaceChild () {
0 commit comments