Skip to content

Commit

Permalink
add retry to InvokeLambdaFunction call
Browse files Browse the repository at this point in the history
  • Loading branch information
djelusic committed Aug 11, 2021
1 parent 903877f commit 4a4264e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 16 deletions.
31 changes: 15 additions & 16 deletions internal/aws/lambda.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,17 @@ func (a *AWS) CreateLambdaFunction(name, role, s3Bucket, s3Key string, layers []
Layers: layers,
}
// lambda creation might fail if the corresponding execution role was just created so we retry until it succeeds
retryInterval := time.Second
retryAttempts := 60
var rsp *lambda.CreateFunctionOutput
var err error
for retryAttempts > 0 {
err = retry(func() error {
rsp, err = a.lambdaClient.CreateFunction(context.Background(), cfi)
if err == nil {
break
}
if strings.Contains(err.Error(), "The role defined for the function cannot be assumed by Lambda") ||
strings.Contains(err.Error(), "The provided execution role does not have permissions") {
time.Sleep(retryInterval)
retryAttempts--
continue
}
if err != nil {
return "", fmt.Errorf("could not create function - %v", err)
}
return err
}, func(err error) bool {
return strings.Contains(err.Error(), "The role defined for the function cannot be assumed by Lambda") ||
strings.Contains(err.Error(), "The provided execution role does not have permissions")
})
if err != nil {
return "", fmt.Errorf("could not create function - %v", err)
}
w := lambda.NewFunctionActiveWaiter(a.lambdaClient)
if err := w.Wait(context.Background(), &lambda.GetFunctionConfigurationInput{
Expand Down Expand Up @@ -85,7 +78,13 @@ func (a *AWS) InvokeLambdaFunction(arn string, req, rsp, clientContext interface
b64Ctx := base64.StdEncoding.EncodeToString(buf)
lii.ClientContext = aws.String(b64Ctx)
}
output, err := a.lambdaClient.Invoke(context.Background(), lii)
var output *lambda.InvokeOutput
err = retry(func() error {
output, err = a.lambdaClient.Invoke(context.Background(), lii)
return err
}, func(err error) bool {
return strings.Contains(err.Error(), "The role defined for the function cannot be assumed by Lambda")
})
if err != nil {
return fmt.Errorf("could not invoke lambda function - %v", err)
}
Expand Down
25 changes: 25 additions & 0 deletions internal/aws/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package aws

import (
"time"
)

func retry(callback func() error, isRetryable func(error) bool) error {
retryInterval := time.Second
retryAttempts := 60
for retryAttempts > 0 {
err := callback()
if err == nil {
break
}
if isRetryable(err) {
time.Sleep(retryInterval)
retryAttempts--
continue
}
if err != nil {
return err
}
}
return nil
}

0 comments on commit 4a4264e

Please sign in to comment.