Documentation
¶
Overview ¶
Package stability ensures service robustness with mechanisms like circuit breakers, retries for transient failures, throttling for rate limiting, debounce for execution control, and timeouts for enforcing execution limits.
Example (Composition) ¶
The wrappers compose: each one takes a Function and returns a Function.
package main
import (
"context"
"fmt"
"time"
"github.com/andygeiss/cloud-native-utils/service"
"github.com/andygeiss/cloud-native-utils/stability"
)
func main() {
calls := 0
backend := service.Wrap(func(in string) (string, error) {
calls++
return "pong", nil
})
fn := stability.Retry(backend, 3, time.Millisecond)
fn = stability.Timeout(fn, time.Second)
out, err := fn(context.Background(), "ping")
fmt.Println(out, err, calls)
}
Output: pong <nil> 1
Index ¶
- Variables
- func Breaker[IN, OUT any](fn service.Function[IN, OUT], threshold int) service.Function[IN, OUT]
- func Debounce[IN, OUT any](fn service.Function[IN, OUT], duration time.Duration) service.Function[IN, OUT]
- func Retry[IN, OUT any](fn service.Function[IN, OUT], maxRetries int, delay time.Duration) service.Function[IN, OUT]
- func Throttle[IN, OUT any](fn service.Function[IN, OUT], maxTokens, refill uint, duration time.Duration) service.Function[IN, OUT]
- func Timeout[IN, OUT any](fn service.Function[IN, OUT], duration time.Duration) service.Function[IN, OUT]
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var (
)
var (
ErrThrottleTooManyCalls = errors.New("too many calls")
)
Functions ¶
func Breaker ¶
Breaker wraps a service function with a circuit breaker mechanism. It tracks failures and prevents further calls when a failure threshold is reached.
Example ¶
package main
import (
"context"
"errors"
"fmt"
"github.com/andygeiss/cloud-native-utils/service"
"github.com/andygeiss/cloud-native-utils/stability"
)
func main() {
failing := service.Wrap(func(in string) (string, error) {
return "", errors.New("backend down")
})
// After two failures the breaker opens and stops calling the backend.
guarded := stability.Breaker(failing, 2)
ctx := context.Background()
for range 3 {
_, err := guarded(ctx, "ping")
fmt.Println(err)
}
}
Output: backend down backend down service unavailable
func Debounce ¶
func Debounce[IN, OUT any](fn service.Function[IN, OUT], duration time.Duration) service.Function[IN, OUT]
Debounce ensures that fn(...) is ultimately called only once if multiple calls arrive within the given duration. Each call waits until that one call finishes, returning the same result/error.
func Retry ¶
func Retry[IN, OUT any](fn service.Function[IN, OUT], maxRetries int, delay time.Duration) service.Function[IN, OUT]
Retry wraps a given function (`fn`) to retry its execution upon failure. The function will be retried up to `maxRetries` times with a delay of `delay` between retries. If the context is canceled during retries, it stops immediately and returns the context error.
Example ¶
package main
import (
"context"
"errors"
"fmt"
"time"
"github.com/andygeiss/cloud-native-utils/service"
"github.com/andygeiss/cloud-native-utils/stability"
)
func main() {
attempts := 0
flaky := service.Wrap(func(in string) (string, error) {
attempts++
if attempts < 3 {
return "", errors.New("temporary failure")
}
return "ok: " + in, nil
})
out, err := stability.Retry(flaky, 5, time.Millisecond)(context.Background(), "ping")
fmt.Println(out, err, attempts)
}
Output: ok: ping <nil> 3
func Throttle ¶
func Throttle[IN, OUT any](fn service.Function[IN, OUT], maxTokens, refill uint, duration time.Duration) service.Function[IN, OUT]
Throttle adds rate-limiting behavior to the provided function (`fn`). The function can only be called up to `maxTokens` times initially, and then tokens are refilled by `refill` every `duration`. If the limit is exceeded, the function returns `ErrThrottleTooManyCalls`.
func Timeout ¶
func Timeout[IN, OUT any](fn service.Function[IN, OUT], duration time.Duration) service.Function[IN, OUT]
Timeout wraps a service.Function and enforces a timeout on its execution. If the function does not complete within the specified duration, the context is canceled, and the function returns an error indicating a timeout.
Example ¶
package main
import (
"context"
"errors"
"fmt"
"time"
"github.com/andygeiss/cloud-native-utils/service"
"github.com/andygeiss/cloud-native-utils/stability"
)
func main() {
slow := service.Wrap(func(in string) (string, error) {
time.Sleep(50 * time.Millisecond)
return in, nil
})
_, err := stability.Timeout(slow, time.Millisecond)(context.Background(), "ping")
fmt.Println(errors.Is(err, context.DeadlineExceeded))
}
Output: true
Types ¶
This section is empty.