8
8
"fmt"
9
9
"io/ioutil"
10
10
"net/http"
11
+ "sync"
11
12
"time"
12
13
13
14
"github.com/xcherryio/apis/goapi/xcapi"
@@ -27,14 +28,15 @@ type immediateTaskConcurrentProcessor struct {
27
28
rootCtx context.Context
28
29
cfg config.Config
29
30
taskToProcessChan chan data_models.ImmediateTask
30
- // for quickly checking if the shardId is being processed
31
- currentShards map [int32 ]bool
32
- // shardId to the channel
31
+ // shardId: channel
33
32
taskToCommitChans map [int32 ]chan <- data_models.ImmediateTask
34
- taskNotifier TaskNotifier
35
- processStore persistence.ProcessStore
36
- visibilityStore persistence.VisibilityStore
37
- logger log.Logger
33
+ // shardId: WaitForProcessCompletionChannels
34
+ waitForProcessCompletionChannelsPerShardMap map [int32 ]WaitForProcessCompletionChannels
35
+ taskNotifier TaskNotifier
36
+ processStore persistence.ProcessStore
37
+ visibilityStore persistence.VisibilityStore
38
+ logger log.Logger
39
+ lock sync.RWMutex
38
40
}
39
41
40
42
func NewImmediateTaskConcurrentProcessor (
@@ -47,12 +49,13 @@ func NewImmediateTaskConcurrentProcessor(
47
49
rootCtx : ctx ,
48
50
cfg : cfg ,
49
51
taskToProcessChan : make (chan data_models.ImmediateTask , bufferSize ),
50
- currentShards : map [int32 ]bool {},
51
52
taskToCommitChans : make (map [int32 ]chan <- data_models.ImmediateTask ),
52
- taskNotifier : notifier ,
53
- processStore : processStore ,
54
- visibilityStore : visibilityStore ,
55
- logger : logger ,
53
+ waitForProcessCompletionChannelsPerShardMap : make (map [int32 ]WaitForProcessCompletionChannels ),
54
+ taskNotifier : notifier ,
55
+ processStore : processStore ,
56
+ visibilityStore : visibilityStore ,
57
+ logger : logger ,
58
+ lock : sync.RWMutex {},
56
59
}
57
60
}
58
61
@@ -66,17 +69,44 @@ func (w *immediateTaskConcurrentProcessor) GetTasksToProcessChan() chan<- data_m
66
69
func (w * immediateTaskConcurrentProcessor ) AddImmediateTaskQueue (
67
70
shardId int32 , tasksToCommitChan chan <- data_models.ImmediateTask ,
68
71
) (alreadyExisted bool ) {
69
- exists := w .currentShards [shardId ]
70
- w .currentShards [shardId ] = true
71
- w .taskToCommitChans [shardId ] = tasksToCommitChan
72
+ w .lock .Lock ()
73
+ defer w .lock .Unlock ()
74
+
75
+ _ , exists := w .taskToCommitChans [shardId ]
76
+ if ! exists {
77
+ w .taskToCommitChans [shardId ] = tasksToCommitChan
78
+ }
79
+
72
80
return exists
73
81
}
74
82
75
83
func (w * immediateTaskConcurrentProcessor ) RemoveImmediateTaskQueue (shardId int32 ) {
76
- delete (w .currentShards , shardId )
84
+ w .lock .Lock ()
85
+ defer w .lock .Unlock ()
86
+
77
87
delete (w .taskToCommitChans , shardId )
78
88
}
79
89
90
+ func (w * immediateTaskConcurrentProcessor ) AddWaitForProcessCompletionChannels (shardId int32 ,
91
+ waitForProcessCompletionChannelsPerShard WaitForProcessCompletionChannels ) (alreadyExisted bool ) {
92
+ w .lock .Lock ()
93
+ defer w .lock .Unlock ()
94
+
95
+ _ , exists := w .waitForProcessCompletionChannelsPerShardMap [shardId ]
96
+ if ! exists {
97
+ w .waitForProcessCompletionChannelsPerShardMap [shardId ] = waitForProcessCompletionChannelsPerShard
98
+ }
99
+
100
+ return exists
101
+ }
102
+
103
+ func (w * immediateTaskConcurrentProcessor ) RemoveWaitForProcessCompletionChannels (shardId int32 ) {
104
+ w .lock .Lock ()
105
+ defer w .lock .Unlock ()
106
+
107
+ delete (w .waitForProcessCompletionChannelsPerShardMap , shardId )
108
+ }
109
+
80
110
func (w * immediateTaskConcurrentProcessor ) Start () error {
81
111
concurrency := w .cfg .AsyncService .ImmediateTaskQueue .ProcessorConcurrency
82
112
@@ -90,15 +120,18 @@ func (w *immediateTaskConcurrentProcessor) Start() error {
90
120
if ! ok {
91
121
return
92
122
}
93
- if ! w .currentShards [task .ShardId ] {
123
+
124
+ _ , exists := w .taskToCommitChans [task .ShardId ]
125
+ if ! exists {
94
126
w .logger .Info ("skip the stale task that is due to shard movement" , tag .Shard (task .ShardId ), tag .ID (task .GetTaskId ()))
95
127
continue
96
128
}
97
129
98
130
err := w .processImmediateTask (w .rootCtx , task )
99
131
100
- if w .currentShards [task .ShardId ] { // check again
101
- commitChan := w .taskToCommitChans [task .ShardId ]
132
+ commitChan , exists := w .taskToCommitChans [task .ShardId ]
133
+
134
+ if exists { // check again
102
135
if err != nil {
103
136
// put it back to the queue for immediate retry
104
137
// Note that if the error is because of invoking worker APIs, it will be sent to
@@ -496,6 +529,15 @@ func (w *immediateTaskConcurrentProcessor) processExecuteTask(
496
529
if compResp .HasNewImmediateTask {
497
530
w .notifyNewImmediateTask (task .ShardId , prep , task )
498
531
}
532
+
533
+ // signal to the process completion waiting channel
534
+ waitForProcessCompletionChannelsPerShard , ok := w .waitForProcessCompletionChannelsPerShardMap [task .ShardId ]
535
+ if ok && compResp .ProcessStatus != data_models .ProcessExecutionStatusUndefined &&
536
+ compResp .ProcessStatus != data_models .ProcessExecutionStatusRunning {
537
+
538
+ waitForProcessCompletionChannelsPerShard .Signal (task .ProcessExecutionId .String (), compResp .ProcessStatus .String ())
539
+ }
540
+
499
541
return nil
500
542
}
501
543
0 commit comments