in pkg/controller/controller.go [1457:1573]
func (c *FrameworkController) syncFrameworkAttemptCompletionPolicy(
f *ci.Framework) (completionPolicyTriggered bool) {
logPfx := fmt.Sprintf("[%v]: syncFrameworkAttemptCompletionPolicy: ", f.Key())
klog.Infof(logPfx + "Started")
defer func() { klog.Infof(logPfx + "Completed") }()
failedTaskSelector := ci.BindIDP((*ci.TaskStatus).IsFailed, true)
succeededTaskSelector := ci.BindIDP((*ci.TaskStatus).IsSucceeded, true)
completedTaskSelector := ci.BindIDP((*ci.TaskStatus).IsCompleted, true)
var firstTriggerTime *meta.Time
var firstTriggerCompletionStatus *ci.FrameworkAttemptCompletionStatus
for _, taskRoleSpec := range f.Spec.TaskRoles {
taskRoleName := taskRoleSpec.Name
taskRoleStatus := f.GetTaskRoleStatus(taskRoleName)
if taskRoleStatus == nil {
// Unreachable
continue
}
completionPolicy := taskRoleSpec.FrameworkAttemptCompletionPolicy
minFailedTaskCount := completionPolicy.MinFailedTaskCount
minSucceededTaskCount := completionPolicy.MinSucceededTaskCount
if minFailedTaskCount >= 1 {
failedTaskCount := taskRoleStatus.GetTaskCountStatus(failedTaskSelector)
if failedTaskCount >= minFailedTaskCount {
trigger := taskRoleStatus.CompletionTimeOrderedTaskStatus(
failedTaskSelector, minFailedTaskCount-1)
if firstTriggerTime == nil || trigger.CompletionTime.Before(firstTriggerTime) {
firstTriggerTime = trigger.CompletionTime
firstTriggerCompletionStatus = ci.NewFailedTaskTriggeredCompletionStatus(
trigger, taskRoleName, failedTaskCount, minFailedTaskCount)
}
}
}
if minSucceededTaskCount >= 1 {
succeededTaskCount := taskRoleStatus.GetTaskCountStatus(succeededTaskSelector)
if succeededTaskCount >= minSucceededTaskCount {
trigger := taskRoleStatus.CompletionTimeOrderedTaskStatus(
succeededTaskSelector, minSucceededTaskCount-1)
if firstTriggerTime == nil || trigger.CompletionTime.Before(firstTriggerTime) {
firstTriggerTime = trigger.CompletionTime
firstTriggerCompletionStatus = ci.NewSucceededTaskTriggeredCompletionStatus(
trigger, taskRoleName, succeededTaskCount, minSucceededTaskCount)
}
}
}
}
if firstTriggerCompletionStatus != nil {
klog.Infof("[%v][%v][%v]: syncFrameworkAttemptCompletionPolicy: %v", f.Key(),
firstTriggerCompletionStatus.Trigger.TaskRoleName,
firstTriggerCompletionStatus.Trigger.TaskIndex,
firstTriggerCompletionStatus.Trigger.Message)
c.completeFrameworkAttempt(f, false, firstTriggerCompletionStatus)
return true
}
totalTaskCount := f.GetTotalTaskCountSpec()
// At least one completed Task is needed to trigger its
// FrameworkAttemptCompletionPolicy.
if totalTaskCount >= 1 {
completedTaskCount := f.GetTaskCountStatus(completedTaskSelector)
// The Framework must not Completing or Completed, so TaskRoles/Tasks in
// f.Spec must fully contain not DeletionPending (ScaleDown) TaskRoles/Tasks
// in f.Status, thus completedTaskCount must <= totalTaskCount.
if completedTaskCount >= totalTaskCount {
var lastCompletedTaskStatus *ci.TaskStatus
var lastCompletedTaskRoleName string
for _, taskRoleSpec := range f.Spec.TaskRoles {
taskRoleName := taskRoleSpec.Name
taskRoleStatus := f.GetTaskRoleStatus(taskRoleName)
if taskRoleStatus == nil {
// Unreachable
continue
}
roleTotalTaskCount := taskRoleSpec.TaskNumber
if roleTotalTaskCount == 0 {
continue
}
roleLastCompletedTask := taskRoleStatus.CompletionTimeOrderedTaskStatus(
completedTaskSelector, roleTotalTaskCount-1)
if lastCompletedTaskStatus == nil ||
roleLastCompletedTask.CompletionTime.Time.After(
lastCompletedTaskStatus.CompletionTime.Time) {
lastCompletedTaskStatus = roleLastCompletedTask
lastCompletedTaskRoleName = taskRoleName
}
}
firstTriggerCompletionStatus = ci.NewCompletedTaskTriggeredCompletionStatus(
lastCompletedTaskStatus, lastCompletedTaskRoleName,
completedTaskCount, totalTaskCount)
if firstTriggerCompletionStatus.Trigger == nil {
klog.Infof("[%v]: syncFrameworkAttemptCompletionPolicy: %v", f.Key(),
firstTriggerCompletionStatus.Diagnostics)
} else {
klog.Infof("[%v][%v][%v]: syncFrameworkAttemptCompletionPolicy: %v", f.Key(),
firstTriggerCompletionStatus.Trigger.TaskRoleName,
firstTriggerCompletionStatus.Trigger.TaskIndex,
firstTriggerCompletionStatus.Trigger.Message)
}
c.completeFrameworkAttempt(f, false, firstTriggerCompletionStatus)
return true
}
}
return false
}