4
4
"context"
5
5
"encoding/json"
6
6
"errors"
7
+ "fmt"
7
8
"log"
8
- "math/rand "
9
+ "sync "
9
10
"time"
10
11
11
12
"github.com/dapr/durabletask-go/backend"
@@ -16,16 +17,18 @@ import (
16
17
func main () {
17
18
// Create a new task registry and add the orchestrator and activities
18
19
r := task .NewTaskRegistry ()
19
- r .AddOrchestrator (RetryActivityOrchestrator )
20
- r .AddActivity (RandomFailActivity )
20
+ must ( r .AddOrchestrator (RetryActivityOrchestrator ) )
21
+ must ( r .AddActivity (RandomFailActivity ) )
21
22
22
23
// Init the client
23
24
ctx := context .Background ()
24
25
client , worker , err := Init (ctx , r )
25
26
if err != nil {
26
27
log .Fatalf ("Failed to initialize the client: %v" , err )
27
28
}
28
- defer worker .Shutdown (ctx )
29
+ defer func () {
30
+ must (worker .Shutdown (ctx ))
31
+ }()
29
32
30
33
// Start a new orchestration
31
34
id , err := client .ScheduleNewOrchestration (ctx , RetryActivityOrchestrator )
@@ -56,7 +59,7 @@ func Init(ctx context.Context, r *task.TaskRegistry) (backend.TaskHubClient, bac
56
59
57
60
// Create a new backend
58
61
// Use the in-memory sqlite provider by specifying ""
59
- be := sqlite .NewSqliteBackend (sqlite .NewSqliteOptions ("" ), logger )
62
+ be := sqlite .NewSqliteBackend (sqlite .NewSqliteOptions ("/Users/javi/projects/javi-durabletask-go/backend/sqlite/retries " ), logger )
60
63
orchestrationWorker := backend .NewOrchestrationWorker (be , executor , logger )
61
64
activityWorker := backend .NewActivityTaskWorker (be , executor , logger )
62
65
taskHubWorker := backend .NewTaskHubWorker (be , orchestrationWorker , activityWorker , logger )
@@ -74,22 +77,89 @@ func Init(ctx context.Context, r *task.TaskRegistry) (backend.TaskHubClient, bac
74
77
}
75
78
76
79
func RetryActivityOrchestrator (ctx * task.OrchestrationContext ) (any , error ) {
77
- if err := ctx .CallActivity (RandomFailActivity , task .WithActivityRetryPolicy (& task.RetryPolicy {
80
+ t := ctx .CallActivity (RandomFailActivity , task .WithActivityRetryPolicy (& task.RetryPolicy {
78
81
MaxAttempts : 10 ,
79
82
InitialRetryInterval : 100 * time .Millisecond ,
80
83
BackoffCoefficient : 2 ,
81
84
MaxRetryInterval : 3 * time .Second ,
82
- })).Await (nil ); err != nil {
85
+ }))
86
+
87
+ t1 := ctx .CallActivity (RandomFailActivity , task .WithActivityRetryPolicy (& task.RetryPolicy {
88
+ MaxAttempts : 10 ,
89
+ InitialRetryInterval : 100 * time .Millisecond ,
90
+ BackoffCoefficient : 2 ,
91
+ MaxRetryInterval : 3 * time .Second ,
92
+ }))
93
+
94
+ if err := t .Await (nil ); err != nil {
83
95
return nil , err
84
96
}
97
+
98
+ if err := t1 .Await (nil ); err != nil {
99
+ return nil , err
100
+ }
101
+
85
102
return nil , nil
86
103
}
87
104
105
+ type Counter struct {
106
+ c int32
107
+ lock sync.Mutex
108
+ }
109
+
110
+ func (c * Counter ) Increment () {
111
+ c .lock .Lock ()
112
+ defer c .lock .Unlock ()
113
+ c .c ++
114
+ }
115
+
116
+ func (c * Counter ) GetValue () int32 {
117
+ c .lock .Lock ()
118
+ defer c .lock .Unlock ()
119
+ return c .c
120
+ }
121
+
122
+ var (
123
+ counters = make (map [string ]* Counter )
124
+ countersLock sync.RWMutex
125
+ )
126
+
127
+ // GetCounter returns a Counter instance for the specified taskExecutionId.
128
+ // If no counter exists for the taskExecutionId, a new one is created.
129
+ func GetCounter (taskExecutionId string ) * Counter {
130
+ countersLock .RLock ()
131
+ counter , exists := counters [taskExecutionId ]
132
+ countersLock .RUnlock ()
133
+
134
+ if ! exists {
135
+ countersLock .Lock ()
136
+ // Check again to handle race conditions
137
+ counter , exists = counters [taskExecutionId ]
138
+ if ! exists {
139
+ counter = & Counter {}
140
+ counters [taskExecutionId ] = counter
141
+ }
142
+ countersLock .Unlock ()
143
+ }
144
+
145
+ return counter
146
+ }
147
+
88
148
func RandomFailActivity (ctx task.ActivityContext ) (any , error ) {
149
+ log .Println (fmt .Sprintf ("#### [%v] activity %v failure" , ctx .GetTaskExecutionId (), ctx .GetTaskID ()))
150
+
89
151
// 70% possibility for activity failure
90
- if rand . Intn ( 100 ) <= 70 {
152
+ if GetCounter ( ctx . GetTaskExecutionId ()). GetValue () != 5 {
91
153
log .Println ("random activity failure" )
154
+ GetCounter (ctx .GetTaskExecutionId ()).Increment ()
92
155
return "" , errors .New ("random activity failure" )
93
156
}
157
+
94
158
return "ok" , nil
95
159
}
160
+
161
+ func must (err error ) {
162
+ if err != nil {
163
+ panic (err )
164
+ }
165
+ }
0 commit comments