@@ -26,6 +26,7 @@ import (
2626 "net"
2727 "strings"
2828 "sync"
29+ "time"
2930
3031 "github.com/go-logr/logr"
3132 "github.com/pkg/errors"
@@ -124,19 +125,20 @@ func (s *actionService) handleRequest(ctx context.Context, req *proto.ActionRequ
124125 if err := checkReconfigure (ctx , req ); err != nil {
125126 return nil , err
126127 }
128+ timeout := resolveTimeout (& action .TimeoutSeconds , req .TimeoutSeconds )
127129 if req .NonBlocking == nil || ! * req .NonBlocking {
128- return blockingCallAction (ctx , action , req .Parameters , & action . TimeoutSeconds )
130+ return callActionWithRetry (ctx , action , req .Parameters , timeout , req . RetryPolicy )
129131 }
130- return s .handleRequestNonBlocking (ctx , req , action )
132+ return s .handleRequestNonBlocking (ctx , req , action , timeout )
131133}
132134
133- func (s * actionService ) handleRequestNonBlocking (ctx context.Context , req * proto.ActionRequest , action * proto.Action ) ([]byte , error ) {
135+ func (s * actionService ) handleRequestNonBlocking (ctx context.Context , req * proto.ActionRequest , action * proto.Action , timeout * int32 ) ([]byte , error ) {
134136 s .mutex .Lock ()
135137 defer s .mutex .Unlock ()
136138
137139 running , ok := s .runningActions [req .Action ]
138140 if ! ok {
139- resultChan , err := nonBlockingCallAction (ctx , action , req .Parameters , & action . TimeoutSeconds )
141+ resultChan , err := nonBlockingCallAction (ctx , action , req .Parameters , timeout )
140142 if err != nil {
141143 return nil , err
142144 }
@@ -155,3 +157,33 @@ func (s *actionService) handleRequestNonBlocking(ctx context.Context, req *proto
155157 }
156158 return (* result ).stdout .Bytes (), nil
157159}
160+
161+ func resolveTimeout (actionTimeout * int32 , requestTimeout * int32 ) * int32 {
162+ if requestTimeout != nil {
163+ return requestTimeout
164+ }
165+ return actionTimeout
166+ }
167+
168+ func callActionWithRetry (ctx context.Context , action * proto.Action , parameters map [string ]string , timeout * int32 , retryPolicy * proto.RetryPolicy ) ([]byte , error ) {
169+ output , err := blockingCallAction (ctx , action , parameters , timeout )
170+ if err == nil || retryPolicy == nil || retryPolicy .MaxRetries <= 0 {
171+ return output , err
172+ }
173+
174+ interval := retryPolicy .RetryInterval
175+ for i := 0 ; i < retryPolicy .MaxRetries ; i ++ {
176+ if interval > 0 {
177+ select {
178+ case <- ctx .Done ():
179+ return nil , ctx .Err ()
180+ case <- time .After (interval ):
181+ }
182+ }
183+ output , err = blockingCallAction (ctx , action , parameters , timeout )
184+ if err == nil {
185+ return output , nil
186+ }
187+ }
188+ return output , err
189+ }
0 commit comments