@@ -129,7 +129,8 @@ func (e *matchingEngineImpl) Stop() {
129
129
}
130
130
131
131
func (e * matchingEngineImpl ) getTaskLists (maxCount int ) (lists []taskListManager ) {
132
- e .taskListsLock .Lock ()
132
+ e .taskListsLock .RLock ()
133
+ defer e .taskListsLock .RUnlock ()
133
134
lists = make ([]taskListManager , 0 , len (e .taskLists ))
134
135
count := 0
135
136
for _ , tlMgr := range e .taskLists {
@@ -139,7 +140,6 @@ func (e *matchingEngineImpl) getTaskLists(maxCount int) (lists []taskListManager
139
140
break
140
141
}
141
142
}
142
- e .taskListsLock .Unlock ()
143
143
return
144
144
}
145
145
@@ -153,20 +153,24 @@ func (e *matchingEngineImpl) String() string {
153
153
return r
154
154
}
155
155
156
- // Returns taskListManager for a task list. If not already cached gets new range from DB and if successful creates one.
156
+ // Returns taskListManager for a task list. If not already cached gets new range from DB and
157
+ // if successful creates one.
157
158
func (e * matchingEngineImpl ) getTaskListManager (taskList * taskListID ) (taskListManager , error ) {
159
+ // The first check is an optimization so almost all requests will have a task list manager
160
+ // and return avoiding the write lock
158
161
e .taskListsLock .RLock ()
159
162
if result , ok := e .taskLists [* taskList ]; ok {
160
163
e .taskListsLock .RUnlock ()
161
164
return result , nil
162
165
}
163
166
e .taskListsLock .RUnlock ()
164
- mgr := newTaskListManager ( e , taskList , e . config )
167
+ // If it gets here, write lock and check again in case a task list is created between the two locks
165
168
e .taskListsLock .Lock ()
166
169
if result , ok := e .taskLists [* taskList ]; ok {
167
170
e .taskListsLock .Unlock ()
168
171
return result , nil
169
172
}
173
+ mgr := newTaskListManager (e , taskList , e .config )
170
174
e .taskLists [* taskList ] = mgr
171
175
e .taskListsLock .Unlock ()
172
176
logging .LogTaskListLoadingEvent (e .logger , taskList .taskListName , taskList .taskType )
@@ -179,6 +183,13 @@ func (e *matchingEngineImpl) getTaskListManager(taskList *taskListID) (taskListM
179
183
return mgr , nil
180
184
}
181
185
186
+ // For use in tests
187
+ func (e * matchingEngineImpl ) updateTaskList (taskList * taskListID , mgr taskListManager ) {
188
+ e .taskListsLock .Lock ()
189
+ defer e .taskListsLock .Unlock ()
190
+ e .taskLists [* taskList ] = mgr
191
+ }
192
+
182
193
func (e * matchingEngineImpl ) removeTaskListManager (id * taskListID ) {
183
194
e .taskListsLock .Lock ()
184
195
defer e .taskListsLock .Unlock ()
@@ -247,7 +258,7 @@ pollLoop:
247
258
// long-poll when frontend calls CancelOutstandingPoll API
248
259
pollerCtx := context .WithValue (ctx , pollerIDKey , pollerID )
249
260
taskList := newTaskListID (domainID , taskListName , persistence .TaskListTypeDecision )
250
- tCtx , err := e .getTask (pollerCtx , taskList )
261
+ tCtx , err := e .getTask (pollerCtx , taskList , nil )
251
262
if err != nil {
252
263
// TODO: Is empty poll the best reply for errPumpClosed?
253
264
if err == ErrNoTasks || err == errPumpClosed {
@@ -341,10 +352,14 @@ pollLoop:
341
352
}
342
353
343
354
taskList := newTaskListID (domainID , taskListName , persistence .TaskListTypeActivity )
355
+ var maxDispatch * float64
356
+ if request .TaskListMetadata != nil {
357
+ maxDispatch = request .TaskListMetadata .MaxTasksPerSecond
358
+ }
344
359
// Add frontend generated pollerID to context so tasklistMgr can support cancellation of
345
360
// long-poll when frontend calls CancelOutstandingPoll API
346
361
pollerCtx := context .WithValue (ctx , pollerIDKey , pollerID )
347
- tCtx , err := e .getTask (pollerCtx , taskList )
362
+ tCtx , err := e .getTask (pollerCtx , taskList , maxDispatch )
348
363
if err != nil {
349
364
// TODO: Is empty poll the best reply for errPumpClosed?
350
365
if err == ErrNoTasks || err == errPumpClosed {
@@ -450,12 +465,14 @@ func (e *matchingEngineImpl) CancelOutstandingPoll(ctx context.Context, request
450
465
}
451
466
452
467
// Loads a task from persistence and wraps it in a task context
453
- func (e * matchingEngineImpl ) getTask (ctx context.Context , taskList * taskListID ) (* taskContext , error ) {
468
+ func (e * matchingEngineImpl ) getTask (
469
+ ctx context.Context , taskList * taskListID , maxDispatchPerSecond * float64 ,
470
+ ) (* taskContext , error ) {
454
471
tlMgr , err := e .getTaskListManager (taskList )
455
472
if err != nil {
456
473
return nil , err
457
474
}
458
- return tlMgr .GetTaskContext (ctx )
475
+ return tlMgr .GetTaskContext (ctx , maxDispatchPerSecond )
459
476
}
460
477
461
478
func (e * matchingEngineImpl ) unloadTaskList (id * taskListID ) {
0 commit comments