aws / aws/aws-toolkit-vscode

Step Functions - Graph not rendering properly in Parallel state

Open
#2,656 0 comments 0 reactions 0 assignees View on GitHub
bug partner-team stepfunctions
Dominant language
TypeScript
Stars
2k
Forks
810
Avg merge
10h 12m
Merged PRs (30d)
7

Description

## Problem

When rendering a definition with certain step types the steps order becomes relevant and the resulting graph becomes incorrect.
This is a bug when rendering the graph. It not only happens on vs code but also on the **Graph view of the AWS console**.

## Steps to reproduce the issue

You can reproduce it parting from the given definition.

```json
{
"StartAt": "ParallelStep",
"States": {
"ParallelStep": {
"Type": "Parallel",
"End": true,
"Branches": [
{
"StartAt": "FIRST_STEP_HERE",
"States": {
"FIRST_STEP_HERE": {
"Next": "SetupIterator",
"Resource": "resource-arn-here",
"Type": "Task"
},
"BeforeDoOperation": {
"Next": "DoOperation",
"Resource": "resource-arn-here",
"Type": "Task"
},
"DoOperation": {
"Next": "IsRejected",
"Resource": "resource-arn-here",
"Type": "Task"
},
"Iterator": {
"Next": "IsIteratorDone",
"Resource": "resource-arn-here",
"Type": "Task"
},
"IsIteratorDone": {
"Choices": [
{
"BooleanEquals": false,
"Variable": "$.variable_name",
"Next": "BeforeDoOperation"
}
],
"Default": "Done",
"Type": "Choice"
},
"Done": {
"End": true,
"Type": "Pass"
},
"IsRejected": {
"Choices": [
{
"BooleanEquals": false,
"Next": "Rejected",
"Variable": "$.variable_name"
}
],
"Default": "Iterator",
"Type": "Choice"
},
"Rejected": {
"Type": "Fail"
},
"SetupIterator": {
"Next": "Iterator",
"Type": "Pass"
}
}
}
]
}
}
}
```

For that given definition the resulting graph is the following:

![image](https://user-images.githubusercontent.com/10915753/170332750-bb502771-575c-41f1-a30a-bcc335997fbf.png)

Until here everything is fine 👍

The problem arise when you're using a tool on top of ASL that moves step ordering.
For instance, here's what happens for almost the same definition. Just moving the `FIRST_STEP_HERE` down one position.

```json
{
"StartAt": "ParallelStep",
"States": {
"ParallelStep": {
"Type": "Parallel",
"End": true,
"Branches": [
{
"StartAt": "FIRST_STEP_HERE",
"States": {
"BeforeDoOperation": {
"Next": "DoOperation",
"Resource": "resource-arn-here",
"Type": "Task"
},
"FIRST_STEP_HERE": {
"Next": "SetupIterator",
"Resource": "resource-arn-here",
"Type": "Task"
},
"DoOperation": {
"Next": "IsRejected",
"Resource": "resource-arn-here",
"Type": "Task"
},
"Iterator": {
"Next": "IsIteratorDone",
"Resource": "resource-arn-here",
"Type": "Task"
},
"IsIteratorDone": {
"Choices": [
{
"BooleanEquals": false,
"Variable": "$.variable_name",
"Next": "BeforeDoOperation"
}
],
"Default": "Done",
"Type": "Choice"
},
"Done": {
"End": true,
"Type": "Pass"
},
"IsRejected": {
"Choices": [
{
"BooleanEquals": false,
"Next": "Rejected",
"Variable": "$.variable_name"
}
],
"Default": "Iterator",
"Type": "Choice"
},
"Rejected": {
"Type": "Fail"
},
"SetupIterator": {
"Next": "Iterator",
"Type": "Pass"
}
}
}
]
}
}
}
```

As you can see in the graph below ⬇️ Now it's totally incorrect and apparently nothing calls the `FIRST_STEP_HERE` ❓

image

Now, if you want to broke the graph just do some more ordering changes:

```json
{
"StartAt": "ParallelStep",
"States": {
"ParallelStep": {
"Type": "Parallel",
"End": true,
"Branches": [
{
"StartAt": "FIRST_STEP_HERE",
"States": {
"BeforeDoOperation": {
"Next": "DoOperation",
"Resource": "resource-arn-here",
"Type": "Task"
},
"FIRST_STEP_HERE": {
"Next": "SetupIterator",
"Resource": "resource-arn-here",
"Type": "Task"
},
"DoOperation": {
"Next": "IsRejected",
"Resource": "resource-arn-here",
"Type": "Task"
},
"Iterator": {
"Next": "IsIteratorDone",
"Resource": "resource-arn-here",
"Type": "Task"
},
"IsIteratorDone": {
"Choices": [
{
"BooleanEquals": false,
"Variable": "$.variable_name",
"Next": "BeforeDoOperation"
}
],
"Default": "Done",
"Type": "Choice"
},
"SetupIterator": {
"Next": "Iterator",
"Type": "Pass"
},
"Done": {
"End": true,
"Type": "Pass"
},
"IsRejected": {
"Choices": [
{
"BooleanEquals": false,
"Next": "Rejected",
"Variable": "$.variable_name"
}
],
"Default": "Iterator",
"Type": "Choice"
},
"Rejected": {
"Type": "Fail"
}
}
}
]
}
}
}
```

image

## Expected behavior

So, given the [language specification](https://states-language.net/spec.html) and as far as I understand ordering shouldn’t be a factor to determine state machine functionality and in fact, if you test this flow, it works as expected so there's a mismatch between the logic and the rendering.

I must also mention that there's a weird combination of step types what produce this error. If you play with the provided definition you may notice that if you remove the `Choice` or the `Done` step, or just if you get the code out of the parallel state everything works fine. I think even if you remove the `BeforeDoOperation` step everything works just perfectly.

## System details (run the `AWS: About Toolkit` command)

- OS: MacOS 12.3.1
- Visual Studio Code version: 1.67.2
- AWS Toolkit version: v1.38.0

Contributor guide

Open the contributing guide

Research direction

Reproduce the issue in the VS Code AWS Toolkit Graph view using the provided Parallel state definitions, changing only the order of States entries. Trace the graph-rendering path responsible for Parallel states and Choice/Pass/Fail combinations; done means equivalent definitions render the same graph regardless of state ordering, with coverage for the supplied cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript, vscode
Domain
devtools, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.