Skip to content

Commit

Permalink
Add Retry Logic for network and instance create (#215)
Browse files Browse the repository at this point in the history
* Add Retry Logic for network and instance create

* rm cmnts
  • Loading branch information
uzaxirr authored Jun 10, 2024
1 parent d36d808 commit 48e8f14
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 8 deletions.
14 changes: 10 additions & 4 deletions civo/instances/resource_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,13 +276,19 @@ func resourceInstanceCreate(ctx context.Context, d *schema.ResourceData, m inter
config.Tags = tags

log.Printf("[INFO] creating the instance %s", d.Get("hostname").(string))
instance, err := apiClient.CreateInstance(config)
err := utils.RetryUntilSuccessOrTimeout(func() error {
instance, err := apiClient.CreateInstance(config)
if err != nil {
return err
}
d.SetId(instance.ID)
return nil
}, 10*time.Second, 2*time.Minute)

if err != nil {
return diag.Errorf("[ERR] failed to create instance: %s", err)
return diag.Errorf("[ERR] failed to create instance after multiple attempts: %s", err)
}

d.SetId(instance.ID)

createStateConf := &resource.StateChangeConf{
Pending: []string{"BUILDING"},
Target: []string{"ACTIVE"},
Expand Down
17 changes: 13 additions & 4 deletions civo/network/resource_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,22 @@ func resourceNetworkCreate(ctx context.Context, d *schema.ResourceData, m interf
if vlanConfig.VlanID > 0 {
configs.VLanConfig = &vlanConfig
}
network, err := apiClient.CreateNetwork(configs)

// Retry the network creation using the utility function
err := utils.RetryUntilSuccessOrTimeout(func() error {
log.Printf("[INFO] Attempting to create the network %s", d.Get("label").(string))
network, err := apiClient.CreateNetwork(configs)
if err != nil {
return err
}
d.SetId(network.ID)
return nil
}, 10*time.Second, 2*time.Minute)

if err != nil {
return diag.Errorf("[ERR] failed to create a new network: %s", err)
return diag.Errorf("[ERR] failed to create a new network after multiple attempts: %s", err)
}

d.SetId(network.ID)

return resourceNetworkRead(ctx, d, m)
}

Expand Down
23 changes: 23 additions & 0 deletions internal/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ package utils
// func ValidateNameSize

import (
"errors"
"fmt"
"log"
"regexp"
"sort"
"strconv"
"strings"
"time"

"github.com/civo/civogo"
"github.com/hashicorp/go-cty/cty"
Expand Down Expand Up @@ -171,3 +174,23 @@ func InPool(id string, list []civogo.KubernetesClusterPoolConfig) bool {
}
return false
}

// FunctionWithError is a type that defines a function returning an error.
type FunctionWithError func() error

// RetryUntilSuccessOrTimeout calls the provided function repeatedly until it returns no error or the timeout has passed.
func RetryUntilSuccessOrTimeout(fn FunctionWithError, interval time.Duration, timeout time.Duration) error {
start := time.Now()
for {
err := fn()
if err != nil {
if time.Since(start) > timeout {
return errors.New("timeout reached")
}
log.Printf("[INFO] Retrying after error: %s", err)
time.Sleep(interval)
continue
}
return nil
}
}

0 comments on commit 48e8f14

Please sign in to comment.