Skip to content
This repository was archived by the owner on Nov 16, 2023. It is now read-only.

Commit 29e1153

Browse files
authored
Pause zero scale Framework instead of completing it (#59)
1 parent d67fc76 commit 29e1153

File tree

2 files changed

+68
-59
lines changed

2 files changed

+68
-59
lines changed

pkg/apis/frameworkcontroller/v1/types.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,11 @@ type FrameworkList struct {
4545
// 2. Partitioned to different heterogeneous TaskRoles which share the same lifecycle
4646
// 3. Ordered in the same homogeneous TaskRole by TaskIndex
4747
// 4. With consistent identity {FrameworkName}-{TaskRoleName}-{TaskIndex} as PodName
48-
// 5. With fine grained RetryPolicy for each Task and the whole Framework
49-
// 6. With fine grained FrameworkAttemptCompletionPolicy for each TaskRole
50-
// 7. With PodGracefulDeletionTimeoutSec for each Task to tune Consistency vs Availability
51-
// 8. With fine grained Status for each TaskAttempt/Task, each TaskRole and the whole
48+
// 5. With fine grained ExecutionType to Start/Stop the whole Framework
49+
// 6. With fine grained RetryPolicy for each Task and the whole Framework
50+
// 7. With fine grained FrameworkAttemptCompletionPolicy for each TaskRole
51+
// 8. With PodGracefulDeletionTimeoutSec for each Task to tune Consistency vs Availability
52+
// 9. With fine grained Status for each TaskAttempt/Task, each TaskRole and the whole
5253
// FrameworkAttempt/Framework
5354
//
5455
// Notes:
@@ -204,14 +205,14 @@ type RetryPolicySpec struct {
204205
// from the Task which triggers the completion.
205206
// 3. If MinSucceededTaskCount >= 1 and MinSucceededTaskCount <= succeeded Task
206207
// count of current TaskRole, immediately complete the FrameworkAttempt, regardless
207-
// of any uncompleted Task, and the CompletionStatus is succeeded which is
208-
// inherited from the Task which triggers the completion.
208+
// of any uncompleted Task, and the CompletionStatus is succeeded which is inherited
209+
// from the Task which triggers the completion.
209210
// 4. If multiple above conditions are satisfied at the same time, the behavior can
210211
// be any one of these satisfied conditions.
211212
// 5. If none of above conditions are satisfied until all Tasks of the Framework are
212-
// completed (including a special case that the Framework does even not have any
213-
// Task), immediately complete the FrameworkAttempt and the CompletionStatus is
214-
// succeeded which is not inherited from any Task.
213+
// completed and the Framework has at least one Task, immediately complete the
214+
// FrameworkAttempt and the CompletionStatus is succeeded which is not inherited
215+
// from any Task.
215216
//
216217
// Notes:
217218
// 1. When the FrameworkAttempt is completed, the FrameworkState is transitioned to

pkg/controller/controller.go

Lines changed: 58 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,53 +1535,57 @@ func (c *FrameworkController) syncFrameworkAttemptCompletionPolicy(
15351535
return true
15361536
}
15371537

1538-
// The Framework must not Completing or Completed, so TaskRoles/Tasks in
1539-
// f.Spec must fully contain not DeletionPending (ScaleDown) TaskRoles/Tasks
1540-
// in f.Status, thus completedTaskCount must <= totalTaskCount.
15411538
totalTaskCount := f.GetTotalTaskCountSpec()
1542-
completedTaskCount := f.GetTaskCountStatus(completedTaskSelector)
1543-
if completedTaskCount >= totalTaskCount {
1544-
var lastCompletedTaskStatus *ci.TaskStatus
1545-
var lastCompletedTaskRoleName string
1546-
for _, taskRoleSpec := range f.Spec.TaskRoles {
1547-
taskRoleName := taskRoleSpec.Name
1548-
taskRoleStatus := f.GetTaskRoleStatus(taskRoleName)
1549-
if taskRoleStatus == nil {
1550-
// Unreachable
1551-
continue
1552-
}
1539+
// At least one completed Task is needed to trigger its
1540+
// FrameworkAttemptCompletionPolicy.
1541+
if totalTaskCount >= 1 {
1542+
completedTaskCount := f.GetTaskCountStatus(completedTaskSelector)
1543+
// The Framework must not Completing or Completed, so TaskRoles/Tasks in
1544+
// f.Spec must fully contain not DeletionPending (ScaleDown) TaskRoles/Tasks
1545+
// in f.Status, thus completedTaskCount must <= totalTaskCount.
1546+
if completedTaskCount >= totalTaskCount {
1547+
var lastCompletedTaskStatus *ci.TaskStatus
1548+
var lastCompletedTaskRoleName string
1549+
for _, taskRoleSpec := range f.Spec.TaskRoles {
1550+
taskRoleName := taskRoleSpec.Name
1551+
taskRoleStatus := f.GetTaskRoleStatus(taskRoleName)
1552+
if taskRoleStatus == nil {
1553+
// Unreachable
1554+
continue
1555+
}
15531556

1554-
roleTotalTaskCount := taskRoleSpec.TaskNumber
1555-
if roleTotalTaskCount == 0 {
1556-
continue
1557-
}
1557+
roleTotalTaskCount := taskRoleSpec.TaskNumber
1558+
if roleTotalTaskCount == 0 {
1559+
continue
1560+
}
15581561

1559-
roleLastCompletedTask := taskRoleStatus.CompletionTimeOrderedTaskStatus(
1560-
completedTaskSelector, roleTotalTaskCount-1)
1562+
roleLastCompletedTask := taskRoleStatus.CompletionTimeOrderedTaskStatus(
1563+
completedTaskSelector, roleTotalTaskCount-1)
15611564

1562-
if lastCompletedTaskStatus == nil ||
1563-
roleLastCompletedTask.CompletionTime.Time.After(
1564-
lastCompletedTaskStatus.CompletionTime.Time) {
1565-
lastCompletedTaskStatus = roleLastCompletedTask
1566-
lastCompletedTaskRoleName = taskRoleName
1565+
if lastCompletedTaskStatus == nil ||
1566+
roleLastCompletedTask.CompletionTime.Time.After(
1567+
lastCompletedTaskStatus.CompletionTime.Time) {
1568+
lastCompletedTaskStatus = roleLastCompletedTask
1569+
lastCompletedTaskRoleName = taskRoleName
1570+
}
15671571
}
1568-
}
15691572

1570-
firstTriggerCompletionStatus = ci.NewCompletedTaskTriggeredCompletionStatus(
1571-
lastCompletedTaskStatus, lastCompletedTaskRoleName,
1572-
completedTaskCount, totalTaskCount)
1573+
firstTriggerCompletionStatus = ci.NewCompletedTaskTriggeredCompletionStatus(
1574+
lastCompletedTaskStatus, lastCompletedTaskRoleName,
1575+
completedTaskCount, totalTaskCount)
15731576

1574-
if firstTriggerCompletionStatus.Trigger == nil {
1575-
klog.Infof("[%v]: syncFrameworkAttemptCompletionPolicy: %v", f.Key(),
1576-
firstTriggerCompletionStatus.Diagnostics)
1577-
} else {
1578-
klog.Infof("[%v][%v][%v]: syncFrameworkAttemptCompletionPolicy: %v", f.Key(),
1579-
firstTriggerCompletionStatus.Trigger.TaskRoleName,
1580-
firstTriggerCompletionStatus.Trigger.TaskIndex,
1581-
firstTriggerCompletionStatus.Trigger.Message)
1577+
if firstTriggerCompletionStatus.Trigger == nil {
1578+
klog.Infof("[%v]: syncFrameworkAttemptCompletionPolicy: %v", f.Key(),
1579+
firstTriggerCompletionStatus.Diagnostics)
1580+
} else {
1581+
klog.Infof("[%v][%v][%v]: syncFrameworkAttemptCompletionPolicy: %v", f.Key(),
1582+
firstTriggerCompletionStatus.Trigger.TaskRoleName,
1583+
firstTriggerCompletionStatus.Trigger.TaskIndex,
1584+
firstTriggerCompletionStatus.Trigger.Message)
1585+
}
1586+
c.completeFrameworkAttempt(f, false, firstTriggerCompletionStatus)
1587+
return true
15821588
}
1583-
c.completeFrameworkAttempt(f, false, firstTriggerCompletionStatus)
1584-
return true
15851589
}
15861590

15871591
return false
@@ -1998,18 +2002,22 @@ func (c *FrameworkController) syncTaskState(
19982002
return nil
19992003
}
20002004

2001-
// The Framework must not Completing or Completed, so TaskRoles/Tasks in
2002-
// f.Spec must fully contain not DeletionPending (ScaleDown) TaskRoles/Tasks
2003-
// in f.Status, thus completedTaskCount must <= totalTaskCount.
20042005
totalTaskCount := f.GetTotalTaskCountSpec()
2005-
completedTaskCount := f.GetTaskCountStatus(completedTaskSelector)
2006-
if completedTaskCount >= totalTaskCount {
2007-
triggerCompletionStatus = ci.NewCompletedTaskTriggeredCompletionStatus(
2008-
taskStatus, taskRoleName, completedTaskCount, totalTaskCount)
2009-
2010-
klog.Info(logPfx + triggerCompletionStatus.Trigger.Message)
2011-
c.completeFrameworkAttempt(f, false, triggerCompletionStatus)
2012-
return nil
2006+
// At least one completed Task is needed to trigger its
2007+
// FrameworkAttemptCompletionPolicy.
2008+
if taskStatus.IsCompleted(true) && totalTaskCount >= 1 {
2009+
completedTaskCount := f.GetTaskCountStatus(completedTaskSelector)
2010+
// The Framework must not Completing or Completed, so TaskRoles/Tasks in
2011+
// f.Spec must fully contain not DeletionPending (ScaleDown) TaskRoles/Tasks
2012+
// in f.Status, thus completedTaskCount must <= totalTaskCount.
2013+
if completedTaskCount >= totalTaskCount {
2014+
triggerCompletionStatus = ci.NewCompletedTaskTriggeredCompletionStatus(
2015+
taskStatus, taskRoleName, completedTaskCount, totalTaskCount)
2016+
2017+
klog.Info(logPfx + triggerCompletionStatus.Trigger.Message)
2018+
c.completeFrameworkAttempt(f, false, triggerCompletionStatus)
2019+
return nil
2020+
}
20132021
}
20142022

20152023
return nil

0 commit comments

Comments
 (0)