Skip to content

Commit 28b3bab

Browse files
authored
GoSteps v1 [#13]
Merge pull request #13 from TanmoySG/v1 GoSteps Version 1 The v1 introduces breaking changes to how steps are defined, GoSteps types, context and execution. Note: Existing v0.3.0-beta steps will no longer be supported by v1 go-steps and would have to be migrated to the new types. To use existing go-steps v0.3.* users of the library should not upgrade to v1.
2 parents 9192236 + 50c7f3a commit 28b3bab

File tree

15 files changed

+1085
-544
lines changed

15 files changed

+1085
-544
lines changed

README.md

Lines changed: 287 additions & 166 deletions
Large diffs are not rendered by default.
-197 KB
Binary file not shown.

example/dynamic-steps-example/main.go

Lines changed: 0 additions & 46 deletions
This file was deleted.

example/multistep-example/main.go

Lines changed: 92 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,81 +2,114 @@ package main
22

33
import (
44
"fmt"
5-
"time"
65

76
gosteps "github.com/TanmoySG/go-steps"
8-
"github.com/TanmoySG/go-steps/example/funcs"
97
)
108

11-
const (
12-
stepMultiply = "Multiply"
13-
stepDivide = "Divide"
14-
)
9+
func main() {
1510

16-
// reading/maintaining this is a bit tricky will add
17-
// a functional way to create this in the next version
18-
var steps = gosteps.Step{
19-
Function: funcs.Add,
20-
StepArgs: []interface{}{2},
21-
NextStep: &gosteps.Step{
22-
Function: funcs.Sub,
23-
StepArgs: []interface{}{4},
24-
NextStepResolver: nextStepResolver,
25-
PossibleNextSteps: gosteps.PossibleNextSteps{
26-
{
27-
Name: stepMultiply,
28-
Function: funcs.Multiply,
29-
StepArgs: []interface{}{-5},
30-
NextStep: &gosteps.Step{
31-
Function: funcs.Add,
32-
StepArgs: []interface{}{100},
33-
NextStep: &gosteps.Step{
34-
Function: funcs.StepWillError3Times,
35-
ErrorsToRetry: []error{
36-
fmt.Errorf("error"),
37-
},
38-
NextStep: &gosteps.Step{
39-
Function: funcs.StepWillErrorInfinitely,
40-
ErrorsToRetry: []error{
41-
fmt.Errorf("error"),
11+
ctx := gosteps.NewGoStepsContext()
12+
13+
multipleDivide := gosteps.Step{
14+
Name: "multipleDivide",
15+
Function: func(c gosteps.GoStepsCtx) gosteps.StepResult {
16+
res := c.GetData("result").(int) * 2
17+
return gosteps.MarkStateComplete().WithData(map[string]interface{}{
18+
"result": res,
19+
})
20+
},
21+
Branches: &gosteps.Branches{
22+
Resolver: func(ctx gosteps.GoStepsCtx) gosteps.BranchName {
23+
nx := ctx.GetData("result").(int)
24+
25+
if nx%2 == 0 {
26+
return gosteps.BranchName("divide")
27+
}
28+
return gosteps.BranchName("multiple")
29+
},
30+
Branches: []gosteps.Branch{
31+
{
32+
BranchName: "divide",
33+
Steps: gosteps.Steps{
34+
{
35+
Name: "step3.divide",
36+
Function: func(c gosteps.GoStepsCtx) gosteps.StepResult {
37+
res := c.GetData("result").(int) / 2
38+
return gosteps.MarkStateComplete().WithData(map[string]interface{}{
39+
"result": res,
40+
})
4241
},
43-
NextStep: &gosteps.Step{
44-
Function: funcs.Multiply,
42+
},
43+
},
44+
},
45+
{
46+
BranchName: "multiply",
47+
Steps: gosteps.Steps{
48+
{
49+
Name: "step3.multiply",
50+
Function: func(c gosteps.GoStepsCtx) gosteps.StepResult {
51+
res := c.GetData("result").(int) * 2
52+
return gosteps.MarkStateComplete().WithData(map[string]interface{}{
53+
"result": res,
54+
})
4555
},
46-
StrictErrorCheck: false,
47-
MaxAttempts: 5, // use gosteps.MaxMaxAttempts for Maximum Possible reattempts
4856
},
49-
MaxAttempts: 5,
50-
RetrySleep: 1 * time.Second,
5157
},
5258
},
5359
},
54-
{
55-
Name: stepDivide,
56-
Function: funcs.Divide,
57-
StepArgs: []interface{}{-2},
60+
},
61+
}
62+
63+
steps := gosteps.Steps{
64+
{
65+
Name: "add",
66+
Function: func(c gosteps.GoStepsCtx) gosteps.StepResult {
67+
68+
res := c.GetData("n1").(int) + c.GetData("n2").(int)
69+
return gosteps.MarkStateComplete().WithData(map[string]interface{}{
70+
"result": res,
71+
})
72+
},
73+
StepArgs: map[string]interface{}{
74+
"n1": 5,
75+
"n2": 4,
5876
},
5977
},
60-
},
61-
}
78+
{
79+
Name: "subtract",
80+
Function: func(c gosteps.GoStepsCtx) gosteps.StepResult {
81+
res := c.GetData("n1").(int) - c.GetData("result").(int)
82+
return gosteps.MarkStateComplete().WithData(map[string]interface{}{
83+
"result": res,
84+
})
85+
},
86+
StepArgs: map[string]interface{}{
87+
"n1": 5,
88+
},
89+
},
90+
multipleDivide,
91+
{
92+
Name: "add",
93+
Function: func(c gosteps.GoStepsCtx) gosteps.StepResult {
94+
res := c.GetData("result").(int) + 5
6295

63-
func main() {
64-
initArgs := []interface{}{5}
65-
finalOutput, err := steps.Execute(initArgs...)
66-
if err != nil {
67-
fmt.Printf("error executing steps: %s, final output: [%s]\n", err, finalOutput)
96+
return gosteps.MarkStateComplete().WithData(map[string]interface{}{
97+
"result": res,
98+
})
99+
},
100+
},
101+
{
102+
Name: "print",
103+
Function: func(c gosteps.GoStepsCtx) gosteps.StepResult {
104+
fmt.Println("result", c.GetData("result"))
105+
return gosteps.MarkStateComplete()
106+
},
107+
},
68108
}
69109

70-
fmt.Printf("Final Output: [%v]\n", finalOutput)
71-
}
72-
73-
// step resolver
74-
func nextStepResolver(args ...any) string {
75-
if args[0].(int) < 0 {
76-
fmt.Printf("StepResolver [%v]: Arguments is Negative, going with Multiply\n", args)
77-
return stepMultiply
110+
root := gosteps.RootStep{
111+
Steps: steps,
78112
}
79113

80-
fmt.Printf("StepResolver [%v]: Arguments is Positive, going with Divide\n", args)
81-
return stepDivide
114+
root.Execute(ctx)
82115
}

go-step-arch.jpg

759 KB
Loading

go.mod

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
11
module github.com/TanmoySG/go-steps
22

33
go 1.18
4-
5-
require github.com/stretchr/testify v1.8.4
6-
7-
require (
8-
github.com/davecgh/go-spew v1.1.1 // indirect
9-
github.com/pmezard/go-difflib v1.0.0 // indirect
10-
gopkg.in/yaml.v3 v3.0.1 // indirect
11-
)

go.sum

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +0,0 @@
1-
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2-
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3-
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4-
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5-
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
6-
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
7-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
8-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
9-
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
10-
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

go_step_context.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package gosteps
2+
3+
import (
4+
"encoding/json"
5+
)
6+
7+
type GoStepsCtxData map[string]interface{}
8+
9+
type GoStepsCtx struct {
10+
Data GoStepsCtxData `json:"data"`
11+
StepsProgress map[StepName]StepProgress `json:"stepsProgress"`
12+
}
13+
14+
type GoStepsContext interface {
15+
getCtx() GoStepsCtx
16+
SetData(key string, value interface{})
17+
GetData(key string) interface{}
18+
WithData(data map[string]interface{})
19+
}
20+
21+
func NewGoStepsContext() GoStepsContext {
22+
return GoStepsCtx{
23+
Data: GoStepsCtxData{},
24+
StepsProgress: map[StepName]StepProgress{},
25+
}
26+
}
27+
28+
func (ctx GoStepsCtx) ToJson() (string, error) {
29+
cBytes, err := json.Marshal(ctx)
30+
if err != nil {
31+
return "", err
32+
}
33+
34+
return string(cBytes), nil
35+
}
36+
37+
func (ctx GoStepsCtx) getCtx() GoStepsCtx {
38+
return ctx
39+
}
40+
41+
func (ctx GoStepsCtx) SetData(key string, value interface{}) {
42+
ctx.Data[key] = value
43+
}
44+
45+
func (ctx GoStepsCtx) GetData(key string) interface{} {
46+
return ctx.Data[key]
47+
}
48+
49+
func (ctx GoStepsCtx) WithData(data map[string]interface{}) {
50+
for key, value := range data {
51+
ctx.SetData(key, value)
52+
}
53+
}
54+
55+
func (ctx GoStepsCtx) SetProgress(step StepName, stepResult StepResult) GoStepsCtx {
56+
ctx.StepsProgress[step] = StepProgress{
57+
StepName: step,
58+
StepResult: stepResult,
59+
}
60+
61+
return ctx
62+
}
63+
64+
func (ctx GoStepsCtx) GetProgress(step StepName) StepProgress {
65+
return ctx.StepsProgress[step]
66+
}
67+
68+
// func (ctx GoStepsCtx) SetStepRetires(stepName StepName) GoStepsCtx {
69+
// progress := ctx.StepsProgress[stepName]
70+
// progress.StepRetries += 1
71+
// ctx.StepsProgress[stepName] = progress
72+
// return ctx
73+
// }

go_step_result.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package gosteps
2+
3+
type StepState string
4+
5+
const (
6+
StepStateComplete StepState = "StepStateComplete" // step completed successfully
7+
StepStateFailed StepState = "StepStateFailed" // step failed to complete, without error
8+
StepStateSkipped StepState = "StepStateSkipped" // step was skipped
9+
StepStatePending StepState = "StepStatePending" // step is pending, should be retried
10+
StepStateError StepState = "StepStateError" // step failed to complete, with error
11+
)
12+
13+
type StepResult struct {
14+
StepData GoStepsCtxData `json:"stepData"`
15+
StepState StepState `json:"stepState"`
16+
StepMessage *string `json:"stepMessage"`
17+
StepError *StepError `json:"stepError,omitempty"`
18+
}
19+
20+
type StepError struct {
21+
StepErrorNameOrId string `json:"stepErrorNameOrId"`
22+
StepErrorMessage string `json:"stepErrorMessage"`
23+
}
24+
25+
type StepProgress struct {
26+
StepName StepName `json:"stepName"`
27+
StepResult StepResult `json:"stepResult"`
28+
}
29+
30+
func MarkState(state StepState) StepResult {
31+
return StepResult{
32+
StepState: state,
33+
}
34+
}
35+
36+
func MarkStateComplete() StepResult {
37+
return MarkState(StepStateComplete)
38+
}
39+
40+
func MarkStateFailed() StepResult {
41+
return MarkState(StepStateFailed)
42+
}
43+
44+
func MarkStateSkipped() StepResult {
45+
return MarkState(StepStateSkipped)
46+
}
47+
48+
func MarkStatePending() StepResult {
49+
return MarkState(StepStatePending)
50+
}
51+
52+
func MarkStateError() StepResult {
53+
return MarkState(StepStateError)
54+
}
55+
56+
func (sr StepResult) WithData(data GoStepsCtxData) StepResult {
57+
sr.StepData = data
58+
return sr
59+
}
60+
61+
func (sr StepResult) WithMessage(message string) StepResult {
62+
sr.StepMessage = &message
63+
return sr
64+
}
65+
66+
func (sr StepResult) WithWrappedError(e error) StepResult {
67+
sr.StepError = &StepError{
68+
StepErrorNameOrId: "error",
69+
StepErrorMessage: e.Error(),
70+
}
71+
return sr
72+
}
73+
74+
func (sr StepResult) WithStepError(stepErr StepError) StepResult {
75+
sr.StepError = &stepErr
76+
return sr
77+
}

0 commit comments

Comments
 (0)