Skip to content

Commit

Permalink
handle ratelimits for reading user groups
Browse files Browse the repository at this point in the history
  • Loading branch information
svenwltr committed Oct 21, 2021
1 parent ffa5f07 commit d3dd77e
Showing 1 changed file with 52 additions and 3 deletions.
55 changes: 52 additions & 3 deletions slack/resource_usergroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ package slack

import (
"context"
"errors"
"fmt"
"math/rand"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/slack-go/slack"
)
Expand Down Expand Up @@ -51,6 +55,10 @@ func resourceSlackUserGroup() *schema.Resource {
Optional: true,
},
},

Timeouts: &schema.ResourceTimeout{
Read: schema.DefaultTimeout(5 * time.Minute),
},
}
}

Expand Down Expand Up @@ -109,10 +117,28 @@ func resourceSlackUserGroupCreate(ctx context.Context, d *schema.ResourceData, m
func resourceSlackUserGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client := m.(*slack.Client)
id := d.Id()
var diags diag.Diagnostics
userGroups, err := client.GetUserGroupsContext(ctx, slack.GetUserGroupsOptionIncludeUsers(true))

var (
diags diag.Diagnostics
userGroups []slack.UserGroup
backoff = &Backoff{Base: time.Second, Cap: 15 * time.Second}
)
err := resource.RetryContext(ctx, d.Timeout(schema.TimeoutRead), func() *resource.RetryError {
var (
err error
rlerr *slack.RateLimitedError
)
userGroups, err = client.GetUserGroupsContext(ctx, slack.GetUserGroupsOptionIncludeUsers(true))
if errors.As(err, &rlerr) {
backoff.Sleep(ctx)
return resource.RetryableError(err)
} else if err != nil {
return resource.NonRetryableError(fmt.Errorf("couldn't get usergroups: %w", err))
}
return nil
})
if err != nil {
return diag.FromErr(fmt.Errorf("couldn't get usergroups: %w", err))
return diag.FromErr(err)
}

for _, userGroup := range userGroups {
Expand All @@ -128,6 +154,29 @@ func resourceSlackUserGroupRead(ctx context.Context, d *schema.ResourceData, m i
return diags
}

type Backoff struct {
Attempt int
Base time.Duration
Cap time.Duration
}

func (b *Backoff) Sleep(ctx context.Context) {
b.Attempt++

wait := b.Base * (2 << b.Attempt)
if wait > b.Cap {
wait = b.Cap
}

wait = time.Duration(rand.Int63n(int64(wait)))

select {
case <-time.After(wait):
case <-ctx.Done():
}

}

func findUserGroupByName(ctx context.Context, name string, includeDisabled bool, m interface{}) (slack.UserGroup, error) {
client := m.(*slack.Client)
userGroups, err := client.GetUserGroupsContext(ctx, slack.GetUserGroupsOptionIncludeDisabled(includeDisabled), slack.GetUserGroupsOptionIncludeUsers(true))
Expand Down

0 comments on commit d3dd77e

Please sign in to comment.