func()

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
}