wilfred-s commented on code in PR #384:
URL: https://github.com/apache/yunikorn-core/pull/384#discussion_r843612422


##########
pkg/scheduler/objects/application_state.go:
##########
@@ -172,6 +175,9 @@ func NewAppState() *fsm.FSM {
                        },
                        fmt.Sprintf("leave_%s", Running.String()): func(event 
*fsm.Event) {
                                app := event.Args[0].(*Application) 
//nolint:errcheck
+                               if app.queue != nil {

Review Comment:
   The app must have a queue set if it is in running state, there is no need 
for a nil check



##########
pkg/scheduler/objects/queue.go:
##########
@@ -1292,3 +1303,42 @@ func (sq *Queue) String() string {
        return fmt.Sprintf("{QueuePath: %s, State: %s, StateTime: %x, 
MaxResource: %s}",
                sq.QueuePath, sq.stateMachine.Current(), sq.stateTime, 
sq.maxResource)
 }
+
+func (sq *Queue) incRunningApps() {

Review Comment:
   Should this increment and decrement below be using a lock on update?
   Do need to make sure we do not lock the whole hierarchy, see 
incPendingResource for example.



##########
pkg/scheduler/objects/queue.go:
##########
@@ -1292,3 +1303,42 @@ func (sq *Queue) String() string {
        return fmt.Sprintf("{QueuePath: %s, State: %s, StateTime: %x, 
MaxResource: %s}",
                sq.QueuePath, sq.stateMachine.Current(), sq.stateTime, 
sq.maxResource)
 }
+
+func (sq *Queue) incRunningApps() {
+       sq.runningApps++
+       if sq.parent != nil {
+               sq.parent.incRunningApps()
+       }
+}
+
+func (sq *Queue) decRunningApps() {
+       sq.runningApps--
+       if sq.parent != nil {
+               sq.parent.decRunningApps()
+       }
+}
+
+func (sq *Queue) canRun() bool {
+       sq.RLock()
+       defer sq.RUnlock()

Review Comment:
   This will lock the current queue and then walk up the tree, locking all 
parents.
   Please follow the same structure as we have for all over: first walk up the 
tree, check the top and then when unwinding check the current queue. Locking 
only when the current queue is checked (see getHeadRoom as an example)



##########
pkg/scheduler/objects/queue.go:
##########
@@ -1292,3 +1303,42 @@ func (sq *Queue) String() string {
        return fmt.Sprintf("{QueuePath: %s, State: %s, StateTime: %x, 
MaxResource: %s}",
                sq.QueuePath, sq.stateMachine.Current(), sq.stateTime, 
sq.maxResource)
 }
+
+func (sq *Queue) incRunningApps() {
+       sq.runningApps++
+       if sq.parent != nil {
+               sq.parent.incRunningApps()
+       }
+}
+
+func (sq *Queue) decRunningApps() {
+       sq.runningApps--
+       if sq.parent != nil {
+               sq.parent.decRunningApps()
+       }
+}
+
+func (sq *Queue) canRun() bool {
+       sq.RLock()
+       defer sq.RUnlock()
+       if sq.maxRunningApps == 0 {
+               return true
+       }
+       ok := sq.runningApps <= sq.maxRunningApps
+       if sq.parent != nil {
+               return ok && sq.parent.canRun()
+       }
+       return ok
+}
+
+func (sq *Queue) GetRunningApps() uint64 {
+       sq.RLock()
+       defer sq.RUnlock()
+       return sq.runningApps
+}
+
+func (sq *Queue) SetMaxRunningApps(maxApps uint64) {
+       sq.RLock()
+       defer sq.RUnlock()

Review Comment:
   This is a read lock securing a write action...
   Also please comment that this is test only as it is not called from anywhere 
else.



##########
pkg/scheduler/objects/utilities_test.go:
##########
@@ -35,25 +35,27 @@ const (
        appID2  = "app-2"
        aKey    = "alloc-1"
        nodeID1 = "node-1"
+       zero    = uint64(0)
 )
 
 // Create the root queue, base for all testing
 func createRootQueue(maxRes map[string]string) (*Queue, error) {
-       return createManagedQueueWithProps(nil, "root", true, maxRes, nil)
+       return createManagedQueueWithProps(nil, "root", true, maxRes, nil, zero)
 }
 
 // wrapper around the create call using the one syntax for all queue types
-func createManagedQueue(parentSQ *Queue, name string, parent bool, maxRes 
map[string]string) (*Queue, error) {
-       return createManagedQueueWithProps(parentSQ, name, parent, maxRes, nil)
+func createManagedQueue(parentSQ *Queue, name string, parent bool, maxRes 
map[string]string, maxApps uint64) (*Queue, error) {

Review Comment:
   Instead of changing this signature add a new function that allows setting 
max apps and leave this as is. i.e. `createManagedQueueMaxApps(....)` calling 
the next one with a 0 value



##########
pkg/scheduler/objects/queue.go:
##########
@@ -1067,6 +1073,11 @@ func (sq *Queue) TryAllocate(iterator func() 
NodeIterator) *Allocation {
                headRoom := sq.getHeadRoom()
                // process the apps (filters out app without pending requests)
                for _, app := range sq.sortApplications(true) {
+                       if !app.IsRunning() && !app.queue.canRun() {

Review Comment:
   You are in the queue, should not access the app for this info. It also does 
not change while walking over the application list. You can pre-calculate the 
value and use it.



##########
pkg/scheduler/objects/utilities_test.go:
##########
@@ -35,25 +35,27 @@ const (
        appID2  = "app-2"
        aKey    = "alloc-1"
        nodeID1 = "node-1"
+       zero    = uint64(0)
 )
 
 // Create the root queue, base for all testing
 func createRootQueue(maxRes map[string]string) (*Queue, error) {
-       return createManagedQueueWithProps(nil, "root", true, maxRes, nil)
+       return createManagedQueueWithProps(nil, "root", true, maxRes, nil, zero)
 }
 
 // wrapper around the create call using the one syntax for all queue types
-func createManagedQueue(parentSQ *Queue, name string, parent bool, maxRes 
map[string]string) (*Queue, error) {
-       return createManagedQueueWithProps(parentSQ, name, parent, maxRes, nil)
+func createManagedQueue(parentSQ *Queue, name string, parent bool, maxRes 
map[string]string, maxApps uint64) (*Queue, error) {
+       return createManagedQueueWithProps(parentSQ, name, parent, maxRes, nil, 
maxApps)
 }
 
 // create managed queue with props set
-func createManagedQueueWithProps(parentSQ *Queue, name string, parent bool, 
maxRes, props map[string]string) (*Queue, error) {
+func createManagedQueueWithProps(parentSQ *Queue, name string, parent bool, 
maxRes, props map[string]string, maxApps uint64) (*Queue, error) {

Review Comment:
   Instead of changing this signature add a new function that allows setting 
max apps and leave this as is. i.e. `createManagedQueuePropsMaxApps(....)`
   Move the real code there and make `createManagedQueueWithProps()` call that 
one



##########
pkg/scheduler/objects/application_state.go:
##########
@@ -143,6 +143,9 @@ func NewAppState() *fsm.FSM {
                        },
                        fmt.Sprintf("enter_%s", Starting.String()): func(event 
*fsm.Event) {
                                app := event.Args[0].(*Application) 
//nolint:errcheck
+                               if app.queue != nil {

Review Comment:
   The app must have a queue set if it is in starting state, there is no need 
for a nil check



-- 
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