-
Notifications
You must be signed in to change notification settings - Fork 4.3k
feat(stepfunctions): retrieve all reachable states from a given state in a state machine definition #7324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(stepfunctions): retrieve all reachable states from a given state in a state machine definition #7324
Conversation
4de59c8 to
cfe7b60
Compare
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
cfe7b60 to
3b066c6
Compare
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
3b066c6 to
3b82f72
Compare
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
27db11a to
29639cd
Compare
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
|
Updated tests because of #7351. |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution! 😊
Could you add your motivation or use case (to the commit message) on why you're adding this method and how you plan to use it?
Hi! Thanks for reviewing. I tried to be more explicit now. Please let me know if more information is needed. |
|
Hi @andrestone - thanks for updating. I'm not sure I quite follow what you've said. Can you expand or provide a concrete example? |
Sure. This method takes an original definition and adds a ResumeTo Choice state to the top of the chain, programatically adding each existing state id as a Choice condition to be matched. private static transformToResumable(definition: sf.IChainable): sf.IChainable {
// Building a set of States
const states = new Set<sf.State>();
// All states starting from a giving state (using the method of this PR)
sf.State.findReachableStates(definition.startState).forEach(state => {
states.add(state);
});
// Here we add our ResumeTo logic to the top of the chain
const choices = new sf.Choice(scope, "ResumeTo");
// We used Set to ensure we have only a single state, although it's redundant with
// the method implementation
let statesArray = Array.from(states);
// For each pre-existing state, we add a Choice condition
for (let i = 0; i < statesArray.length; i++) {
choices.when(sf.Condition.stringEquals('$.resumeTo', statesArray[i].id), statesArray[i]);
}
// The default is the original definition
choices.otherwise(definition);
// This is our new State Machine definition ready to accept `resumeTo` as part of the input
// to resume the execution starting from the referred state
return choices
}Should I add this to the commit message? Thanks. |
|
I tried to rewrite the description, it was indeed confusing. Not sure if it's clear enough now, though. Thanks for reviewing. |
|
Thanks! This does sound interesting. I've re-worded the commit message as per this. Feel free to adjust it if I was inaccurate. |
It's definitely better, but I think it's important to mention we're dealing with the State Machine definition, not the State Machine itself. Just for clarity. |
| To retrieve all possible subsequent states from an initial state, you can use the | ||
| method `State.findReachableStates`: | ||
|
|
||
| ```typescript | ||
| import * as sf from '@aws-cdk/aws-stepfunctions'; | ||
| const nextState = sf.State.findReachableStates(startState); // All reachable / next states | ||
| ``` | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need the code block for this since the API is straightforward. How about changing it to something like this -
| To retrieve all possible subsequent states from an initial state, you can use the | |
| method `State.findReachableStates`: | |
| ```typescript | |
| import * as sf from '@aws-cdk/aws-stepfunctions'; | |
| const nextState = sf.State.findReachableStates(startState); // All reachable / next states | |
| ``` | |
| A few utility functions are available to parse state machine fragments. | |
| * `State.findReachableStates`: Retrieve the list of states reachable from a given state. | |
| * `State.findReachableEndStates`: Retrieve the list of end or terminal states reachable from a given state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| .branch(state2)).toThrow(); | ||
| }), | ||
|
|
||
| test('Can retrieve possible states from initial state', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need more test cases here -
- Assert that this behaves correctly when there is a Choice and Parallel states included.
- Assert that states that are not reachable are not returned.
Wrap these test cases inside of a describe clause -
describe('findReachableStates', () => {
test('Can retrieve possible states from initial state', () => {
...
});
});There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The construct sees the Parallel branches as separate State Machines, so none of the private methods used to compute the subsequent states actually care about them. It looks to me like it's a design decision that is out of the scope of this PR.
Therefore, the states inside a Parallel states are not retrieved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not so sure that this is a conscious design choice.
It seems to me that outgoingTransitions() should take an additional option called includeBranches (which defaults to false) and considers all the branches (this.state) of the current state as well.
Otherwise, this utility function is incomplete.
cc @rix0rrr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parallel branches are separate state machines, as far as I'm aware, so yes this was done consciously. Let me read the rest of the thread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not so sure that this is a conscious design choice.
It seems to me that
outgoingTransitions()should take an additional option calledincludeBranches(which defaults tofalse) and considers all the branches (this.state) of the current state as well.Otherwise, this utility function is incomplete.
cc @rix0rrr.
I like this approach better. Please let me know if I should add it in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we don't need this yet, let's leave the implementation as is, and add explicit documentation to the tsdoc that these states are not returned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok!
29639cd to
4ab3ffa
Compare
|
I accidentally force pushed a wrong commit. Trying to make this PR survive the mess, |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
|
I guess I should put more effort into understanding the purpose behind this PR, but I'm short on time so I'll just throw this out:
If we keep roughly to the current approach, given that we want a I will admit the API between |
Hi, @rix0rrr, thanks for your interest. As per what I can understand, the What I'm trying to accomplish here, is to programatically modify (most likely not in place, such as demonstrated in the example above) a state machine definition somewhere out of the scope of its original declaration. In order to do that, I need to have access to those chained objects. As mentioned in the original issue, I couldn't find anyway to do it, hence this PR.
I think it would also make sense to have the method as part of the |
packages/@aws-cdk/aws-stepfunctions/test/states-language.test.ts
Outdated
Show resolved
Hide resolved
packages/@aws-cdk/aws-stepfunctions/test/states-language.test.ts
Outdated
Show resolved
Hide resolved
| .branch(state2)).toThrow(); | ||
| }), | ||
|
|
||
| test('Can retrieve possible states from initial state', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we don't need this yet, let's leave the implementation as is, and add explicit documentation to the tsdoc that these states are not returned.
nija-at
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making the changes. A few more minor tweaks and this should be ready to go.
… in a state machine definition
c2a5bf1 to
64a6826
Compare
|
Done! Only extra is that I switched the assertions to Thanks, @nija-at. |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
nija-at
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making those changes. Approved!
Our mergify bot will take it from here and merge this PR into our master branch.
|
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
|
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Commit Message
feat(stepfunctions): retrieve all reachable states from a given state in a state machine definition (#7324)
A new method -
findReachableStates- to retrieve all reachable states subsequent to a given initial state, including itself.Motivation
With this method, developers can programatically modify their state definitions, given an initial state.
For example, walk through the set of states and attach some of them to a 'ResumeTo' Choice state, so that state machine executions can jump directly to one of these states.
closes #7256
End Commit Message
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license