### Install backoff library Source: https://github.com/jpillora/backoff/blob/master/README.md This command installs the backoff library for Go projects using the go get command. It fetches the latest version of the library and makes it available for import in your Go code. ```bash go get -v github.com/jpillora/backoff ``` -------------------------------- ### Basic Backoff with Duration() in Go Source: https://context7.com/jpillora/backoff/llms.txt Demonstrates the basic usage of the Backoff struct in Go. It initializes a backoff counter with specified min, max, and factor, and uses the Duration() method to get exponentially increasing delays. The internal attempt counter is tracked and can be reset. Dependencies include the standard 'fmt', 'time', and 'github.com/jpillora/backoff' packages. ```go package main import ( "fmt" "time" "github.com/jpillora/backoff" ) func main() { b := &backoff.Backoff{ Min: 100 * time.Millisecond, Max: 10 * time.Second, Factor: 2, Jitter: false, } // Each call increments the internal counter fmt.Printf("Attempt 1: %s\n", b.Duration()) // Output: 100ms fmt.Printf("Attempt 2: %s\n", b.Duration()) // Output: 200ms fmt.Printf("Attempt 3: %s\n", b.Duration()) // Output: 400ms fmt.Printf("Attempt 4: %s\n", b.Duration()) // Output: 800ms // Reset counter back to zero b.Reset() fmt.Printf("After reset: %s\n", b.Duration()) // Output: 100ms } ``` -------------------------------- ### HTTP Client Retry with Custom Factor Source: https://context7.com/jpillora/backoff/llms.txt Demonstrates implementing HTTP request retry logic using a custom backoff factor. This example shows how to integrate the backoff library into a loop to handle transient network errors, with a gentler progression (Factor: 1.5) compared to the default factor of 2. ```go package main import ( "fmt" "net/http" "time" "github.com/jpillora/backoff" ) func main() { b := &backoff.Backoff{ Min: 500 * time.Millisecond, Max: 30 * time.Second, Factor: 1.5, Jitter: true, } maxRetries := 5 url := "https://api.example.com/data" for b.Attempt() < float64(maxRetries) { resp, err := http.Get(url) if err == nil && resp.StatusCode == 200 { fmt.Println("Request successful") resp.Body.Close() break } if resp != nil { resp.Body.Close() } if b.Attempt() >= float64(maxRetries-1) { fmt.Printf("Max retries reached, giving up\n") break } d := b.Duration() fmt.Printf("Attempt %.0f failed, retrying in %s\n", b.Attempt(), d) time.Sleep(d) } } ``` -------------------------------- ### Get Current Attempt Count with Attempt() Source: https://context7.com/jpillora/backoff/llms.txt Retrieves the current attempt counter value of a backoff instance. This is useful for monitoring retry progress and implementing conditional logic based on the number of retries performed. The counter is incremented each time Duration() is called and reset when Reset() is called. ```go package main import ( "fmt" "time" "github.com/jpillora/backoff" ) func main() { b := &backoff.Backoff{ Min: 100 * time.Millisecond, Max: 10 * time.Second, Factor: 2, } fmt.Printf("Initial attempt: %.0f\n", b.Attempt()) b.Duration() fmt.Printf("After 1st Duration(): %.0f\n", b.Attempt()) b.Duration() b.Duration() fmt.Printf("After 3 Duration() calls: %.0f\n", b.Attempt()) if b.Attempt() > 5 { fmt.Println("Too many attempts, giving up") } b.Reset() fmt.Printf("After reset: %.0f\n", b.Attempt()) } ``` -------------------------------- ### Network Retry Pattern with Backoff in Go Source: https://context7.com/jpillora/backoff/llms.txt Shows a practical network retry pattern in Go using exponential backoff. It attempts to establish a network connection, and if it fails, it uses the Backoff struct to calculate and wait for increasing durations before retrying. Successful connections reset the backoff counter. Dependencies include 'fmt', 'net', 'time', and 'github.com/jpillora/backoff'. ```go package main import ( "fmt" "net" "time" "github.com/jpillora/backoff" ) func main() { b := &backoff.Backoff{ Min: 1 * time.Second, Max: 5 * time.Minute, Factor: 2, } for { conn, err := net.Dial("tcp", "example.com:5309") if err != nil { d := b.Duration() fmt.Printf("Connection failed: %s, reconnecting in %s\n", err, d) time.Sleep(d) continue } // Connection successful - reset backoff b.Reset() // Use connection _, writeErr := conn.Write([]byte("hello world!")) if writeErr != nil { fmt.Printf("Write error: %s\n", writeErr) } conn.Close() break } } ``` -------------------------------- ### Clone Backoff Configuration with Copy() Source: https://context7.com/jpillora/backoff/llms.txt Creates an independent copy of a backoff instance. This allows multiple independent retry sequences to be managed from a single base configuration without affecting each other's state. Each copy maintains its own attempt counter and duration sequence. ```go package main import ( "fmt" "time" "github.com/jpillora/backoff" ) func main() { template := &backoff.Backoff{ Min: 100 * time.Millisecond, Max: 5 * time.Second, Factor: 2, Jitter: true, } operation1 := template.Copy() operation2 := template.Copy() fmt.Printf("Op1 attempt 1: %s\n", operation1.Duration()) fmt.Printf("Op1 attempt 2: %s\n", operation1.Duration()) fmt.Printf("Op2 attempt 1: %s\n", operation2.Duration()) fmt.Printf("Op1 Factor: %.0f\n", operation1.Factor) fmt.Printf("Op2 Factor: %.0f\n", operation2.Factor) } ``` -------------------------------- ### Basic backoff usage in Go Source: https://github.com/jpillora/backoff/blob/master/README.md Demonstrates the fundamental usage of the backoff counter. It initializes a backoff object with default or custom Min, Max, Factor, and Jitter settings. Subsequent calls to Duration() return increasing delays multiplied by the Factor, capped by Max. Reset() returns the duration to Min. ```go b := &backoff.Backoff{ //These are the defaults Min: 100 * time.Millisecond, Max: 10 * time.Second, Factor: 2, Jitter: false, } fmt.Printf("%s\n", b.Duration()) fmt.Printf("%s\n", b.Duration()) fmt.Printf("%s\n", b.Duration()) fmt.Printf("Reset!\n") b.Reset() fmt.Printf("%s\n", b.Duration()) ``` -------------------------------- ### ForAttempt() - Stateless Backoff Calculation in Go Source: https://context7.com/jpillora/backoff/llms.txt Demonstrates the stateless `ForAttempt()` function in Go, which calculates the backoff duration for a specific attempt number without altering the internal state of the `Backoff` object. This is useful for scenarios requiring independent backoff calculations or parallel processing. Dependencies include 'fmt', 'time', and 'github.com/jpillora/backoff'. ```go package main import ( "fmt" "time" "github.com/jpillora/backoff" ) func main() { b := &backoff.Backoff{ Min: 100 * time.Millisecond, Max: 10 * time.Second, Factor: 2, } // Calculate durations for specific attempts (0-indexed) fmt.Printf("Attempt 0: %s\n", b.ForAttempt(0)) // Output: 100ms fmt.Printf("Attempt 1: %s\n", b.ForAttempt(1)) // Output: 200ms fmt.Printf("Attempt 2: %s\n", b.ForAttempt(2)) // Output: 400ms fmt.Printf("Attempt 5: %s\n", b.ForAttempt(5)) // Output: 3.2s fmt.Printf("Attempt 10: %s\n", b.ForAttempt(10)) // Output: 10s (capped at Max) // ForAttempt doesn't modify internal state fmt.Printf("First Duration() call: %s\n", b.Duration()) // Output: 100ms (starts at attempt 0) } ``` -------------------------------- ### Concurrent-Safe Backoff Usage with ForAttempt() Source: https://context7.com/jpillora/backoff/llms.txt Demonstrates thread-safe backoff calculation across multiple goroutines using the ForAttempt() method. This approach allows each goroutine to independently calculate its backoff duration for a specific attempt number without requiring shared mutable state, preventing race conditions. ```go package main import ( "fmt" "sync" "time" "github.com/jpillora/backoff" ) func main() { b := &backoff.Backoff{ Min: 100 * time.Millisecond, Max: 10 * time.Second, Factor: 2, } wg := &sync.WaitGroup{} for i := 0; i < 5; i++ { wg.Add(1) go func(attempt int) { defer wg.Done() duration := b.ForAttempt(float64(attempt)) fmt.Printf("Goroutine attempt %d: sleep for %s\n", attempt, duration) time.Sleep(duration) }(i) } wg.Wait() fmt.Println("All goroutines completed") } ``` -------------------------------- ### Backoff with net package for retries in Go Source: https://github.com/jpillora/backoff/blob/master/README.md Illustrates using the backoff counter with the net package for network connection retries. If a connection fails, the code waits for a backoff duration before attempting to reconnect. On successful connection, the backoff counter is reset. ```go b := &backoff.Backoff{ Max: 5 * time.Minute, } for { conn, err := net.Dial("tcp", "example.com:5309") if err != nil { d := b.Duration() fmt.Printf("%s, reconnecting in %s", err, d) time.Sleep(d) continue } //connected b.Reset() conn.Write([]byte("hello world!")) // ... Read ... Write ... etc conn.Close() //disconnected } ``` -------------------------------- ### Jitter-Enabled Backoff in Go Source: https://context7.com/jpillora/backoff/llms.txt Illustrates how to use jitter with the Backoff library in Go to prevent synchronized retries. When Jitter is enabled, the backoff durations are randomized within a range determined by the current backoff value, adhering to AWS best practices. Dependencies include 'fmt', 'math/rand', 'time', and 'github.com/jpillora/backoff'. ```go package main import ( "fmt" "math/rand" "time" "github.com/jpillora/backoff" ) func main() { b := &backoff.Backoff{ Min: 100 * time.Millisecond, Max: 10 * time.Second, Factor: 2, Jitter: true, } // Seed for reproducible results (optional) rand.Seed(42) // With jitter, durations are randomized between min and calculated value fmt.Printf("Attempt 1: %s\n", b.Duration()) // Output: ~100ms (always min on first) fmt.Printf("Attempt 2: %s\n", b.Duration()) // Output: ~106ms (100-200ms range) fmt.Printf("Attempt 3: %s\n", b.Duration()) // Output: ~281ms (100-400ms range) b.Reset() fmt.Printf("After reset: %s\n", b.Duration()) // Output: ~100ms fmt.Printf("Attempt 2: %s\n", b.Duration()) // Output: ~104ms (100-200ms range) } ``` -------------------------------- ### Backoff with Jitter enabled in Go Source: https://github.com/jpillora/backoff/blob/master/README.md Shows how to enable jitter for randomized backoff durations. Jitter adds randomness to the delays, which can improve performance in distributed systems by reducing the chance of simultaneous retries. Seeding the random number generator provides repeatable results for testing. ```go import "math/rand" b := &backoff.Backoff{ Jitter: true, } rand.Seed(42) fmt.Printf("%s\n", b.Duration()) fmt.Printf("%s\n", b.Duration()) fmt.Printf("%s\n", b.Duration()) fmt.Printf("Reset!\n") b.Reset() fmt.Printf("%s\n", b.Duration()) fmt.Printf("%s\n", b.Duration()) fmt.Printf("%s\n", b.Duration()) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.