diff --git a/README.md b/README.md index c4d80398..ba18c2ef 100644 --- a/README.md +++ b/README.md @@ -101,48 +101,6 @@ Client, err = meraki.NewClient() devicesCount, _, err := Client.Devices.GetDeviceCount() ``` -## Backoff and Jitter Configuration - -The client allows you to configure the retry (backoff) strategy with jitter to avoid collisions when retrying failed requests. This can be adjusted using environment variables or directly in the code. - -### Environment Variables - -- `MERAKI_RETRIES`: Maximum number of retries (default: 3) -- `MERAKI_RETRY_DELAY`: Base wait time between retries, in milliseconds (default: 1000 ms) -- `MERAKI_RETRY_JITTER`: Maximum random jitter added to the backoff, in milliseconds (default: 3000 ms) -- `MERAKI_USE_RETRY_HEADER`: If set to `true`, the client will respect the `Retry-After` header from API responses (default: false) - -Example: - -```sh -export MERAKI_RETRIES=5 -export MERAKI_RETRY_DELAY=2000 -export MERAKI_RETRY_JITTER=5000 -export MERAKI_USE_RETRY_HEADER=true -``` - -### How does backoff with jitter work? - -On each retry, the SDK adds to the base wait time (`MERAKI_RETRY_DELAY`) a random value between 0 and `MERAKI_RETRY_JITTER`, to avoid multiple clients retrying at the same time: - -``` -wait_time = RETRY_DELAY + random(0, RETRY_JITTER) -``` - -If `MERAKI_USE_RETRY_HEADER` is set to `true`, the client will also respect the `Retry-After` header sent by the API, if present, to determine the wait time before the next retry. - -### Default values - -- `MERAKI_RETRIES`: **3** -- `MERAKI_RETRY_DELAY`: **1000 ms** -- `MERAKI_RETRY_JITTER`: **3000 ms** -- `MERAKI_USE_RETRY_HEADER`: **false** - -If the environment variables are not set, these default values will be used. - ---- - - ## Examples Here is an example of how we can generate a client, get a device count and then a list of devices filtering them using query params. @@ -172,6 +130,85 @@ client, err = meraki.NewClientWithOptions("https://api.meraki.com/", [dashboard-api-go](https://pkg.go.dev/github.com/meraki/dashboard-api-go) +### Rate Limiting and Retry Configuration + +The client allows you to configure automatic retry (backoff) behavior for rate-limited (HTTP 429) responses using the `SetBackoff` method. This is useful to control how and how many times the SDK retries requests when the API responds with rate limits. + +#### Using SetBackoff + +```go +// Example of custom backoff configuration +maxRetries := 5 // Maximum number of retries (total attempts = maxRetries + 1) +maxRetryDelay := 2 * time.Second // Base wait time for exponential backoff between retries +maxRetryJitter := 3 * time.Second // Maximum random jitter to add to the backoff +useRetryHeader := true // Whether to respect the Retry-After header if present + +err := client.SetBackoff(&maxRetries, &maxRetryDelay, &maxRetryJitter, &useRetryHeader) +if err != nil { + fmt.Println("Error configuring backoff:", err) +} +``` + +#### SetBackoff Parameters + +- `maxRetries` (`*int`): Maximum number of retries before failing. If `nil`, the default is 2 (3 total attempts). +- `maxRetryDelay` (`*time.Duration`): Base wait time for exponential backoff. If `nil`, the default is 1 second. +- `maxRetryJitter` (`*time.Duration`): Maximum random jitter to add to the backoff. If `nil`, the default is 3 seconds. +- `useRetryHeader` (`*bool`): If `true`, the client will respect the `Retry-After` header in the response to determine the wait time before retrying. If `nil`, the default is `false`. + +#### Default Values + +If you do not call `SetBackoff`, the following defaults are used: +- `maxRetries`: 2 (3 total attempts) +- `maxRetryDelay`: 1 second +- `maxRetryJitter`: 3 seconds +- `useRetryHeader`: false + +#### Behavior + +- Backoff is exponential: the wait time doubles on each attempt, plus a random jitter. +- If the response includes a `Retry-After` header and `useRetryHeader` is `true`, that value will be used as the wait time. +- The backoff mechanism is automatically applied to all calls that receive an HTTP 429 (rate limit). + +#### Complete Example + +```go +package main + +import ( + "fmt" + "time" + meraki "github.com/meraki/dashboard-api-go/sdk" +) + +func main() { + client, err := meraki.NewClient() + if err != nil { + fmt.Println(err) + return + } + + maxRetries := 5 + maxRetryDelay := 2 * time.Second + maxRetryJitter := 3 * time.Second + useRetryHeader := true + + err = client.SetBackoff(&maxRetries, &maxRetryDelay, &maxRetryJitter, &useRetryHeader) + if err != nil { + fmt.Println("Error configuring backoff:", err) + return + } + + // All calls will now use this backoff configuration + nResponse, _, err := client.Organizations.GetOrganizations() + if err != nil { + fmt.Println(err) + return + } + fmt.Println(nResponse) +} +``` + ## Compatibility matrix | SDK versions | MERAKI Dashboard version supported |