craigcondit commented on code in PR #587:
URL: https://github.com/apache/yunikorn-k8shim/pull/587#discussion_r1191705692


##########
pkg/cache/application.go:
##########
@@ -62,6 +63,68 @@ type Application struct {
        placeholderTimeoutInSec    int64
        schedulingStyle            string
        originatingTask            interfaces.ManagedTask // Original Pod which 
creates the requests
+
+       newTasks *newTasksTracker
+}
+
+// For performance reasons, we track tasks with "New" state for quick 
retrieval.
+// Application.GetNewTasks (and getTasks() in general) must not be used on 
critical paths because it
+// uses a read lock inside fsm.FSM which becomes a bottleneck with large 
number of pods.
+type newTasksTracker struct {
+       sortedTasks *btree.BTree
+       sync.Mutex

Review Comment:
   Shouldn't we use an RWMutex here as reads are likely to (significantly) 
outstrip writes?



##########
pkg/cache/application_test.go:
##########
@@ -1343,3 +1343,64 @@ func (ctx *Context) addApplication(app *Application) {
        defer ctx.lock.Unlock()
        ctx.applications[app.applicationID] = app
 }
+
+func TestNewTaskTracker(t *testing.T) {
+       context := initContextForTest()
+       ms := newMockSchedulerAPI()
+       app := NewApplication(appID, "root.abc", "testuser", testGroups, 
map[string]string{}, ms)
+       tasks := []*Task{
+               NewTask("task01", app, context,
+                       &v1.Pod{
+                               ObjectMeta: apis.ObjectMeta{
+                                       CreationTimestamp: apis.Time{Time: 
time.Unix(100, 0)},
+                               },
+                       },
+               ),
+               NewTask("task02", app, context,
+                       &v1.Pod{
+                               ObjectMeta: apis.ObjectMeta{
+                                       CreationTimestamp: apis.Time{Time: 
time.Unix(11, 0)},
+                               },
+                       },
+               ),
+               NewTask("task03", app, context,
+                       &v1.Pod{
+                               ObjectMeta: apis.ObjectMeta{
+                                       CreationTimestamp: apis.Time{Time: 
time.Unix(22, 0)},
+                               },
+                       },
+               ),
+               NewTask("task04", app, context,
+                       &v1.Pod{
+                               ObjectMeta: apis.ObjectMeta{
+                                       CreationTimestamp: apis.Time{Time: 
time.Unix(50, 0)},
+                               },
+                       },
+               ),
+               NewTask("task05", app, context,
+                       &v1.Pod{
+                               ObjectMeta: apis.ObjectMeta{
+                                       CreationTimestamp: apis.Time{Time: 
time.Unix(1, 0)},
+                               },
+                       },
+               ),
+       }
+
+       for _, task := range tasks {
+               app.addTask(task)
+       }
+       verifyNewTaskOrding(t, app)
+       app.removeTask("task04")
+       app.removeTask("task05")
+       verifyNewTaskOrding(t, app)
+       assert.Equal(t, 3, app.newTasks.count())
+}
+
+func verifyNewTaskOrding(t *testing.T, app *Application) {
+       newTasks := app.GetNewTasks()

Review Comment:
   I think app.GetNewTasks() should be refactored to use the new method. 
There's no point in leaving the old mechanism around. We can add an 
`app.HasNewTasks() bool` method as well for quickly determining if the list is 
empty.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to