go.uber.org/cadence@v1.2.9/test/replaytests/parallel_workflow.go (about) 1 // Copyright (c) 2017 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package replaytests 22 23 import ( 24 "errors" 25 "fmt" 26 "time" 27 28 "go.uber.org/zap" 29 30 "go.uber.org/cadence/workflow" 31 ) 32 33 /** 34 * This sample workflow executes multiple branches in parallel using workflow.Go() method. 35 */ 36 37 // sampleParallelWorkflow workflow decider 38 func sampleParallelWorkflow(ctx workflow.Context) error { 39 waitChannel := workflow.NewChannel(ctx) 40 41 ao := workflow.ActivityOptions{ 42 ScheduleToStartTimeout: time.Minute, 43 StartToCloseTimeout: time.Minute, 44 HeartbeatTimeout: time.Second * 20, 45 } 46 ctx = workflow.WithActivityOptions(ctx, ao) 47 48 logger := workflow.GetLogger(ctx) 49 workflow.Go(ctx, func(ctx workflow.Context) { 50 err := workflow.ExecuteActivity(ctx, sampleActivity, "branch1.1").Get(ctx, nil) 51 if err != nil { 52 logger.Error("Activity failed", zap.Error(err)) 53 waitChannel.Send(ctx, err.Error()) 54 return 55 } 56 err = workflow.ExecuteActivity(ctx, sampleActivity, "branch1.2").Get(ctx, nil) 57 if err != nil { 58 logger.Error("Activity failed", zap.Error(err)) 59 waitChannel.Send(ctx, err.Error()) 60 return 61 } 62 waitChannel.Send(ctx, "") 63 }) 64 65 workflow.Go(ctx, func(ctx workflow.Context) { 66 err := workflow.ExecuteActivity(ctx, sampleActivity, "branch2").Get(ctx, nil) 67 if err != nil { 68 logger.Error("Activity failed", zap.Error(err)) 69 waitChannel.Send(ctx, err.Error()) 70 return 71 } 72 waitChannel.Send(ctx, "") 73 }) 74 75 // wait for both of the coroutinue to complete. 76 var errMsg string 77 for i := 0; i != 2; i++ { 78 waitChannel.Receive(ctx, &errMsg) 79 if errMsg != "" { 80 err := errors.New(errMsg) 81 logger.Error("Coroutine failed", zap.Error(err)) 82 return err 83 } 84 } 85 86 logger.Info("Workflow completed.") 87 return nil 88 } 89 90 // Removing one branch from coroutine 1 made no difference. Here we remove one branch ie branch1.2from the coroutine 1. ` 91 func sampleParallelWorkflow2(ctx workflow.Context) error { 92 waitChannel := workflow.NewChannel(ctx) 93 94 ao := workflow.ActivityOptions{ 95 ScheduleToStartTimeout: time.Minute, 96 StartToCloseTimeout: time.Minute, 97 HeartbeatTimeout: time.Second * 20, 98 } 99 ctx = workflow.WithActivityOptions(ctx, ao) 100 101 logger := workflow.GetLogger(ctx) 102 workflow.Go(ctx, func(ctx workflow.Context) { 103 err := workflow.ExecuteActivity(ctx, sampleActivity, "branch1.1").Get(ctx, nil) 104 if err != nil { 105 logger.Error("Activity failed", zap.Error(err)) 106 waitChannel.Send(ctx, err.Error()) 107 return 108 } 109 waitChannel.Send(ctx, "") 110 }) 111 112 workflow.Go(ctx, func(ctx workflow.Context) { 113 err := workflow.ExecuteActivity(ctx, sampleActivity, "branch2").Get(ctx, nil) 114 if err != nil { 115 logger.Error("Activity failed", zap.Error(err)) 116 waitChannel.Send(ctx, err.Error()) 117 return 118 } 119 waitChannel.Send(ctx, "") 120 }) 121 122 // wait for both of the coroutinue to complete. 123 var errMsg string 124 for i := 0; i != 2; i++ { 125 waitChannel.Receive(ctx, &errMsg) 126 if errMsg != "" { 127 err := errors.New(errMsg) 128 logger.Error("Coroutine failed", zap.Error(err)) 129 return err 130 } 131 } 132 133 logger.Info("Workflow completed.") 134 return nil 135 } 136 137 func sampleActivity(input string) (string, error) { 138 name := "sampleActivity" 139 fmt.Printf("Run %s with input %v \n", name, input) 140 return "Result_" + name, nil 141 }