Skip to content

Commit

Permalink
feat: add waiting state for subtasks steps (#331)
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Bétrancourt <thomas@betrancourt.net>
  • Loading branch information
rclsilver authored May 4, 2022
1 parent c8de724 commit dc2cad7
Show file tree
Hide file tree
Showing 17 changed files with 68 additions and 11 deletions.
7 changes: 6 additions & 1 deletion engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,9 @@ forLoop:
case step.StateRunning:
mapStatus[resolution.StateCrashed] = true
allDone = false
case step.StateWaiting:
mapStatus[resolution.StateWaiting] = true
allDone = false
case step.StateTODO:
// instance is in shutdown mode, the resolution may have been interrupted
// set to crashed for proper retry
Expand All @@ -513,7 +516,7 @@ forLoop:
// compute resolution state
if !allDone {
// from candidate resolution states, choose a resolution state by priority
for _, status := range []string{resolution.StateCrashed, resolution.StateBlockedFatal, resolution.StateBlockedBadRequest, resolution.StateError, resolution.StateBlockedDeadlock} {
for _, status := range []string{resolution.StateCrashed, resolution.StateBlockedFatal, resolution.StateBlockedBadRequest, resolution.StateError, resolution.StateBlockedDeadlock, resolution.StateWaiting} {
if mapStatus[status] {
res.SetState(status)
break
Expand All @@ -540,6 +543,8 @@ forLoop:
} else {
res.NextRetry = nextRetry(res)
}
case resolution.StateWaiting:
t.SetState(task.StateWaiting)
case resolution.StateBlockedBadRequest, resolution.StateBlockedFatal, resolution.StateBlockedDeadlock:
t.SetState(task.StateBlocked)
}
Expand Down
2 changes: 1 addition & 1 deletion engine/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ func TestResolveSubTask(t *testing.T) {
res, err = runResolution(res)
require.Nil(t, err)
require.NotNil(t, res)
assert.Equal(t, resolution.StateError, res.State)
assert.Equal(t, resolution.StateWaiting, res.State)

subtaskCreationOutput := res.Steps["subtaskCreation"].Output.(map[string]interface{})
subtaskPublicID := subtaskCreationOutput["id"].(string)
Expand Down
7 changes: 5 additions & 2 deletions engine/step/step.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const (
const (
StateAny = "ANY" // wildcard
StateTODO = "TODO"
StateWaiting = "WAITING"
StateRunning = "RUNNING"
StateDone = "DONE"
StateClientError = "CLIENT_ERROR"
Expand All @@ -60,9 +61,9 @@ const (
)

var (
builtinStates = []string{StateTODO, StateRunning, StateDone, StateClientError, StateServerError, StateFatalError, StateCrashed, StatePrune, StateToRetry, StateRetryNow, StateAfterrunError, StateAny, StateExpanded}
builtinStates = []string{StateTODO, StateWaiting, StateRunning, StateDone, StateClientError, StateServerError, StateFatalError, StateCrashed, StatePrune, StateToRetry, StateRetryNow, StateAfterrunError, StateAny, StateExpanded}
stepConditionValidStates = []string{StateDone, StatePrune, StateToRetry, StateRetryNow, StateFatalError, StateClientError}
runnableStates = []string{StateTODO, StateServerError, StateClientError, StateFatalError, StateCrashed, StateToRetry, StateRetryNow, StateAfterrunError, StateExpanded} // everything but RUNNING, DONE, PRUNE
runnableStates = []string{StateTODO, StateServerError, StateClientError, StateFatalError, StateCrashed, StateToRetry, StateRetryNow, StateAfterrunError, StateExpanded, StateWaiting} // everything but RUNNING, DONE, PRUNE
retriableStates = []string{StateServerError, StateToRetry, StateAfterrunError}
)

Expand Down Expand Up @@ -431,6 +432,8 @@ func Run(st *Step, baseConfig map[string]json.RawMessage, stepValues *values.Val
if err != nil {
if errors.IsBadRequest(err) {
st.State = StateClientError
} else if errors.IsNotAssigned(err) {
st.State = StateWaiting
} else if errors.IsNotProvisioned(err) {
st.State = StateToRetry
} else {
Expand Down
1 change: 1 addition & 0 deletions models/resolution/resolution.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const (

// collectable

StateWaiting = "WAITING"
StateCrashed = "CRASHED"
StateRetry = "RETRY"
StateError = "ERROR" // a step failed, we'll retry, keep the resolution running
Expand Down
7 changes: 4 additions & 3 deletions models/task/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (
StateBlocked = "BLOCKED" // not automatically retriable, 400 bad requests, etc..
StateCancelled = "CANCELLED"
StateWontfix = "WONTFIX"
StateWaiting = "WAITING"
)

// StepError holds an error and the name of the step from where it originated
Expand Down Expand Up @@ -576,7 +577,7 @@ func (t *Task) SetTags(tags map[string]string, values *values.Values) error {
// and input is present and valid given the template spec
func (t *Task) Valid(tt *tasktemplate.TaskTemplate) error {
switch t.State {
case StateTODO, StateRunning, StateDone, StateBlocked, StateCancelled, StateWontfix:
case StateTODO, StateRunning, StateDone, StateBlocked, StateCancelled, StateWontfix, StateWaiting:
break
default:
return errors.BadRequestf("Wrong state: %s", t.State)
Expand Down Expand Up @@ -715,9 +716,9 @@ func (t *Task) ShouldResumeParentTask(dbp zesty.DBProvider) (*Task, error) {
return nil, err
}
switch parentTask.State {
case StateBlocked, StateRunning:
case StateBlocked, StateRunning, StateWaiting:
default:
// not allowed to resume a parent task that is not either Running or Blocked.
// not allowed to resume a parent task that is not either Waiting, Running or Blocked.
// Todo state should not be runned as it might need manual resolution from a granted resolver
return nil, nil
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/plugins/builtin/subtask/subtask.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ func exec(stepName string, config interface{}, ctx interface{}) (interface{}, in
stepError = errors.BadRequestf("Task '%s' changed state: %s", t.PublicID, strings.ToLower(t.State))
case task.StateTODO:
if t.Resolution == nil {
stepError = errors.NewNotProvisioned(fmt.Errorf("Task %q is waiting for human validation", t.PublicID), "")
stepError = errors.NewNotAssigned(fmt.Errorf("Task %q is waiting for human validation", t.PublicID), "")
} else {
stepError = errors.NewNotProvisioned(fmt.Errorf("Task %q will start shortly", t.PublicID), "")
stepError = errors.NewNotAssigned(fmt.Errorf("Task %q will start shortly", t.PublicID), "")
}
case task.StateRunning:
stepError = errors.NewNotProvisioned(fmt.Errorf("Task %q is currently RUNNING", t.PublicID), "")
Expand Down
3 changes: 2 additions & 1 deletion ui/dashboard/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@
"builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"proxyConfig": "proxy.conf.js",
"browserTarget": "utask-ui:build"
"browserTarget": "utask-ui:build",
"disableHostCheck": true
},
"configurations": {
"production": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ export class StepNodeComponent implements OnInit, OnChanges {
this.styleClass = 'prune';
break;
}
case 'WAITING': {
this.styleClass = 'waiting';
break;
}
case 'CLIENT_ERROR':
case 'FATAL_ERROR':
{
Expand Down Expand Up @@ -76,6 +80,10 @@ export class StepNodeComponent implements OnInit, OnChanges {
this.styleClass = 'prune';
break;
}
case 'WAITING': {
this.styleClass = 'waiting';
break;
}
case 'CLIENT_ERROR':
case 'SERVER_ERROR':
case 'FATAL_ERROR':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
.step-red
background: repeating-linear-gradient(45deg, #b04020, #b04020 10px, #B95439 10px, #B95439 20px)
color: white
.step-waiting
background: #8a2be2
color: white
.step-default
background-color: #fab000
background-image: linear-gradient(45deg, #f09000 25%, transparent 25%, transparent 75%, #f09000 75%), linear-gradient(45deg, #f09000 25%, transparent 25%, transparent 75%, #f09000 75%)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { NzNotificationService } from 'ng-zorro-antd/notification';
import Step from '../../@models/step.model';
import { ModalApiYamlEditComponent } from '../../@modals/modal-api-yaml-edit/modal-api-yaml-edit.component';
import { ApiService } from '../../@services/api.service';
import { TasksListComponentOptions } from '../tasks-list/tasks-list.component';

@Component({
selector: 'lib-utask-steps-list',
Expand All @@ -21,6 +22,7 @@ export class StepsListComponent implements OnChanges {
@Input() resolution: any;
@Input() selectedStep: string;
@Output() stepChanged = new EventEmitter<Step>();
@Input() options?: TasksListComponentOptions = new TasksListComponentOptions();
displayDetails: { [key: string]: boolean } = {};
filter: any = {
tags: []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
<nz-list-item *ngFor="let stepName of filteredStepNames" [ngStyle]="lineStyle(stepName)">
{{stepName}}
<nz-button-group nzSize="small" nzType="default">
<button type="button" nzType="default" nz-button [nzGhost]="true" title="Go to subtask"
*ngIf="resolution.steps[stepName].action.type === 'subtask' && resolution.steps[stepName].output.id"
[routerLink]="options.routingTaskPath+resolution.steps[stepName].output.id"
nzTooltipTitle="Go to subtask" nz-tooltip><i nz-icon nzType="link" nzTheme="outline"></i></button>
<button type="button" nzType="default" nz-button [nzGhost]="true" title="View error"
*ngIf="resolution.steps[stepName].error"
(click)="preview('Step '+ resolution.steps[stepName].name, resolution.steps[stepName].error); $event.stopPropagation();"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ $color-danger: #dc3545
$color-warning: #fd7e14
$color-success: #28a745
$color-primary: #007bff
$color-waiting: #8a2be2

.wrapper
display: flex
Expand All @@ -17,6 +18,11 @@ $color-primary: #007bff
background-image: linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, .1) 33%, rgba(0, 0, 0, .1) 66%, transparent 66%)
background-size: 4rem 100%, 100% 100%, 100% 100%
animation: animate-state-running 1s linear infinite
&.WAITING
background-color: $color-waiting
background-image: linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, .1) 33%, rgba(0, 0, 0, .1) 66%, transparent 66%)
background-size: 4rem 100%, 100% 100%, 100% 100%
animation: animate-state-running 1s linear infinite
&.CANCELLED, &.WONTFIX
background: $color-warning
&.BLOCKED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ export enum TaskState {
DONE = 'DONE',
RUNNING = 'RUNNING',
TODO = 'TODO',
WONTFIX = 'WONTFIX'
WONTFIX = 'WONTFIX',
WAITING = 'WAITING'
};

export class Comment {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ export class StatsComponent implements OnInit {
label: 'wontfix',
value: this._route.snapshot.data.stats.task_states['WONTFIX'] || 0
},
{
color: '#8a2be2',
key: 'WAITING',
label: 'waiting',
value: this._route.snapshot.data.stats.task_states['WAITING'] || 0
},
].sort((a, b) => a.value < b.value ? 1 : -1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ $color-warning: #fd7e14
$color-danger: #dc3545
$color-success: #28a745
$color-primary: #007bff
$color-waiting: #8a2be2

:host
display: flex
Expand Down Expand Up @@ -71,6 +72,9 @@ nz-page-header-extra
&_TODO, &_RUNNING
background: $color-primary
color: white
&_WAITING
background: $color-waiting
color: white

lib-utask-steps-list
margin-bottom: 15px
Expand All @@ -95,3 +99,6 @@ lib-utask-steps-viewer
&_TODO, &_RUNNING
background: $color-primary !important
color: white !important
&_WAITING
background: $color-waiting !important
color: white !important
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<nz-option nzValue="RUNNING" nzLabel="Running"></nz-option>
<nz-option nzValue="TODO" nzLabel="Todo"></nz-option>
<nz-option nzValue="WONTFIX" nzLabel="Wontfix"></nz-option>
<nz-option nzValue="WAITING" nzLabel="Waiting"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,14 @@ export class WorkflowService {
isFinal: false,
icon: 'history',
error: false
}, {
key: 'WAITING',
color: '#8a2be2',
fontColor: 'white',
shape: 'shape_blue',
isFinal: false,
icon: 'sync',
error: false
}, {
key: 'RUNNING',
color: '#32acff',
Expand Down

0 comments on commit dc2cad7

Please sign in to comment.