-
Notifications
You must be signed in to change notification settings - Fork 241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[YUNIKORN-2907] Queue config processing log spew #1009
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -79,7 +79,29 @@ | |
locking.RWMutex | ||
} | ||
|
||
// newPartitionContextForValidation initializes a shadow partition based on the configuration. | ||
// The shadow partition is used to validate the configuration, it is not used for scheduling. | ||
func newPartitionContextForValidation(conf configs.PartitionConfig, rmID string, cc *ClusterContext) (*PartitionContext, error) { | ||
pc, err := newPartitionContextInternal(conf, rmID, cc) | ||
if pc != nil { | ||
if err := pc.initialPartitionFromConfigForValidation(conf); err != nil { | ||
return nil, err | ||
} | ||
} | ||
return pc, err | ||
} | ||
|
||
func newPartitionContext(conf configs.PartitionConfig, rmID string, cc *ClusterContext) (*PartitionContext, error) { | ||
pc, err := newPartitionContextInternal(conf, rmID, cc) | ||
if pc != nil { | ||
if err := pc.initialPartitionFromConfig(conf); err != nil { | ||
return nil, err | ||
} | ||
} | ||
return pc, err | ||
} | ||
|
||
func newPartitionContextInternal(conf configs.PartitionConfig, rmID string, cc *ClusterContext) (*PartitionContext, error) { | ||
if conf.Name == "" || rmID == "" { | ||
log.Log(log.SchedPartition).Info("partition cannot be created", | ||
zap.String("partition name", conf.Name), | ||
|
@@ -98,13 +120,41 @@ | |
foreignAllocs: make(map[string]*objects.Allocation), | ||
} | ||
pc.partitionManager = newPartitionManager(pc, cc) | ||
if err := pc.initialPartitionFromConfig(conf); err != nil { | ||
return nil, err | ||
} | ||
|
||
return pc, nil | ||
} | ||
|
||
// initialPartitionFromConfigForValidation is used to validate the partition configuration. | ||
// It works similarly to initialPartitionFromConfig but neither logs the queue creation, sends a queue event, logs the node sorting policy, | ||
// nor updates user settings. | ||
func (pc *PartitionContext) initialPartitionFromConfigForValidation(conf configs.PartitionConfig) error { | ||
if len(conf.Queues) == 0 || conf.Queues[0].Name != configs.RootQueue { | ||
return fmt.Errorf("partition cannot be created without root queue") | ||
} | ||
|
||
// Setup the queue structure: root first it should be the only queue at this level | ||
// Add the rest of the queue structure recursively | ||
queueConf := conf.Queues[0] | ||
var err error | ||
if pc.root, err = objects.NewConfiguredQueueForValidation(queueConf, nil); err != nil { | ||
return err | ||
} | ||
// recursively add the queues to the root | ||
if err = pc.addQueueForValidation(queueConf.Queues, pc.root); err != nil { | ||
return err | ||
} | ||
|
||
// We need to pass in the locked version of the GetQueue function. | ||
// Placing an application will not have a lock on the partition context. | ||
pc.placementManager = placement.NewPlacementManager(conf.PlacementRules, pc.GetQueue) | ||
// get the user group cache for the partition | ||
pc.userGroupCache = security.GetUserGroupCache("") | ||
pc.updateNodeSortingPolicyForValidation(conf) | ||
pc.updatePreemption(conf) | ||
Comment on lines
+147
to
+153
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These lines are unnecessary here. No return values are checked, so whether they run or not is irrelevant. |
||
|
||
return nil | ||
} | ||
|
||
// Initialise the partition | ||
func (pc *PartitionContext) initialPartitionFromConfig(conf configs.PartitionConfig) error { | ||
if len(conf.Queues) == 0 || conf.Queues[0].Name != configs.RootQueue { | ||
|
@@ -138,6 +188,13 @@ | |
return ugm.GetUserManager().UpdateConfig(queueConf, conf.Queues[0].Name) | ||
} | ||
|
||
// updateNodeSortingPolicyForValidation is used to validate the partition configuration. | ||
// It works similarly to updateNodeSortingPolicy but without logging. | ||
// NOTE: this is a lock free call. It should only be called holding the PartitionContext lock. | ||
func (pc *PartitionContext) updateNodeSortingPolicyForValidation(conf configs.PartitionConfig) { | ||
pc.updateNodeSortingPolicyInternal(conf) | ||
} | ||
|
||
// NOTE: this is a lock free call. It should only be called holding the PartitionContext lock. | ||
func (pc *PartitionContext) updateNodeSortingPolicy(conf configs.PartitionConfig) { | ||
var configuredPolicy policies.SortingPolicy | ||
|
@@ -150,6 +207,10 @@ | |
log.Log(log.SchedPartition).Info("NodeSorting policy set from config", | ||
zap.Stringer("policyName", configuredPolicy)) | ||
} | ||
pc.updateNodeSortingPolicyInternal(conf) | ||
} | ||
|
||
func (pc *PartitionContext) updateNodeSortingPolicyInternal(conf configs.PartitionConfig) { | ||
pc.nodes.SetNodeSortingPolicy(objects.NewNodeSortingPolicy(conf.NodeSortPolicy.Type, conf.NodeSortPolicy.ResourceWeights)) | ||
} | ||
|
||
|
@@ -191,17 +252,27 @@ | |
return ugm.GetUserManager().UpdateConfig(queueConf, conf.Queues[0].Name) | ||
} | ||
|
||
func (pc *PartitionContext) addQueueForValidation(conf []configs.QueueConfig, parent *objects.Queue) error { | ||
err := pc.addQueueInternal(conf, parent, objects.NewConfiguredQueueForValidation) | ||
return err | ||
} | ||
|
||
// Process the config structure and create a queue info tree for this partition | ||
func (pc *PartitionContext) addQueue(conf []configs.QueueConfig, parent *objects.Queue) error { | ||
err := pc.addQueueInternal(conf, parent, objects.NewConfiguredQueue) | ||
return err | ||
} | ||
|
||
func (pc *PartitionContext) addQueueInternal(conf []configs.QueueConfig, parent *objects.Queue, newQueueFn func(configs.QueueConfig, *objects.Queue) (*objects.Queue, error)) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you considered passing down a boolean flag
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @pbacsko Thanks for reviewing! I'm not sure about these method duplications either. My first thought is like you said that NewConfiguredQueue() has some callers, adding a flag would require all of them to include an additional parameter. But after implementing these method duplications, the code feels redundant, and it turns out that more test cases need to be covered. I'll try the flag approach. Thanks a lot, my confusion is now cleared! |
||
// create the queue at this level | ||
for _, queueConf := range conf { | ||
thisQueue, err := objects.NewConfiguredQueue(queueConf, parent) | ||
thisQueue, err := newQueueFn(queueConf, parent) | ||
if err != nil { | ||
return err | ||
} | ||
// recursive create the queues below | ||
if len(queueConf.Queues) > 0 { | ||
err = pc.addQueue(queueConf.Queues, thisQueue) | ||
err = pc.addQueueInternal(queueConf.Queues, thisQueue, newQueueFn) | ||
if err != nil { | ||
return err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return value
*PartitionContext
is never used from this function, so you might as well just remove it and just call itvalidateConfiguration()
. Unless of course, you create unit tests which actually use it for some kind of verification... See other comments.