Skip to content

Commit 7de30cd

Browse files
authored
Merge pull request #737 from ystia/backport40/bugfix/gh-733-action-no-stop
[Backport 4.0] Workflow with asynchronous action never stops after another step failure
2 parents 8c536b3 + a5c75ef commit 7de30cd

File tree

5 files changed

+52
-3
lines changed

5 files changed

+52
-3
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## UNRELEASED
44

5+
### BUG FIXES
6+
7+
* Workflow with asynchronous action never stops after another step failure ([GH-733](https://github.com/ystia/yorc/issues/733))
8+
59
## 4.0.6 (May 06, 2021)
610

711
### BUG FIXES

prov/scheduling/scheduler/consul_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,8 @@ func TestRunConsulSchedulingPackageTests(t *testing.T) {
7171
t.Run("testUnregisterAction", func(t *testing.T) {
7272
testUnregisterAction(t, client)
7373
})
74+
t.Run("testUpdateActionData", func(t *testing.T) {
75+
testUpdateActionData(t, client)
76+
})
7477
})
7578
}

prov/scheduling/scheduler/scheduler_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
"github.com/hashicorp/consul/api"
2626
"github.com/stretchr/testify/require"
27+
"gotest.tools/v3/assert"
2728

2829
"github.com/ystia/yorc/v4/events"
2930
"github.com/ystia/yorc/v4/helper/consulutil"
@@ -368,3 +369,30 @@ func testUnregisterAction(t *testing.T, client *api.Client) {
368369
require.NotNil(t, kvp, "kvp is nil")
369370
require.Equal(t, "true", string(kvp.Value), "unregisterFlag is not set to true")
370371
}
372+
373+
func testUpdateActionData(t *testing.T, client *api.Client) {
374+
t.Parallel()
375+
deploymentID := "dep-" + t.Name()
376+
ti := 1 * time.Second
377+
actionType := "test-action"
378+
action := &prov.Action{ActionType: actionType, Data: map[string]string{"key1": "val1", "key2": "val2", "key3": "val3"}}
379+
id, err := scheduling.RegisterAction(client, deploymentID, ti, action)
380+
assert.NilError(t, err, "Failed to register action")
381+
382+
err = scheduling.UpdateActionData(client, id, "key2", "newVal")
383+
assert.NilError(t, err, "Failed to update action data")
384+
385+
testSched := scheduler{cc: client}
386+
newAction, err := testSched.buildScheduledAction(id)
387+
assert.NilError(t, err, "Failed to build action")
388+
389+
val := newAction.Data["key2"]
390+
assert.Equal(t, val, "newVal", "Unexpected value for action key updated")
391+
392+
// Check the update of an unregistered action, should fail
393+
err = testSched.unregisterAction(id)
394+
assert.NilError(t, err, "Failed to unregister action")
395+
396+
err = scheduling.UpdateActionData(client, id, "key3", "newVal")
397+
assert.ErrorContains(t, err, "unregistered")
398+
}

prov/scheduling/scheduling.go

+12-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222

2323
"github.com/hashicorp/consul/api"
2424
"github.com/pkg/errors"
25-
"github.com/satori/go.uuid"
25+
uuid "github.com/satori/go.uuid"
2626

2727
"github.com/ystia/yorc/v4/helper/consulutil"
2828
"github.com/ystia/yorc/v4/log"
@@ -104,7 +104,16 @@ func UnregisterAction(client *api.Client, id string) error {
104104
// UpdateActionData updates the value of a given data within an action
105105
func UpdateActionData(client *api.Client, id, key, value string) error {
106106

107-
//TODO check if action exists
108-
scaKeyPath := path.Join(consulutil.SchedulingKVPrefix, "actions", id, "data", key)
107+
// check if action still exists
108+
actionIdPrefix := path.Join(consulutil.SchedulingKVPrefix, "actions", id)
109+
kvp, _, err := client.KV().Get(path.Join(actionIdPrefix, "deploymentID"), nil)
110+
if err != nil {
111+
return err
112+
}
113+
if kvp == nil {
114+
return errors.Errorf("Action with ID %s is unregistered", id)
115+
}
116+
117+
scaKeyPath := path.Join(actionIdPrefix, "data", key)
109118
return errors.Wrapf(consulutil.StoreConsulKeyAsString(scaKeyPath, value), "Failed to update data %q for action %q", key, id)
110119
}

tasks/workflow/worker.go

+5
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ func (w *worker) runAction(ctx context.Context, t *taskExecution) error {
448448
}
449449
}
450450
wasCancelled := new(bool)
451+
taskFailure := new(bool)
451452
if action.AsyncOperation.TaskID != "" {
452453
ctx = operations.SetOperationLogFields(ctx, action.AsyncOperation.Operation)
453454
ctx = events.AddLogOptionalFields(ctx, events.LogOptionalFields{
@@ -468,6 +469,7 @@ func (w *worker) runAction(ctx context.Context, t *taskExecution) error {
468469
tasks.UpdateTaskStepWithStatus(action.AsyncOperation.TaskID, action.AsyncOperation.StepName, tasks.TaskStepStatusCANCELED)
469470
})
470471
tasks.MonitorTaskFailure(ctx, action.AsyncOperation.TaskID, func() {
472+
*taskFailure = true
471473
// Unregister this action asap to prevent new schedulings
472474
scheduling.UnregisterAction(w.consulClient, action.ID)
473475

@@ -496,6 +498,9 @@ func (w *worker) runAction(ctx context.Context, t *taskExecution) error {
496498
if deregister || *wasCancelled {
497499
scheduling.UnregisterAction(w.consulClient, action.ID)
498500
w.endAction(ctx, t, action, *wasCancelled, err)
501+
} else if *taskFailure {
502+
err = errors.Errorf("Stopped on task failure")
503+
w.endAction(ctx, t, action, *wasCancelled, err)
499504
}
500505
if err != nil {
501506
return err

0 commit comments

Comments
 (0)