feat: add revision number to proxy and layers to identify changes
All checks were successful
Cadoles/bouncer/pipeline/head This commit looks good
All checks were successful
Cadoles/bouncer/pipeline/head This commit looks good
This commit is contained in:
@ -3,10 +3,18 @@ package redis
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"gitlab.com/wpetit/goweb/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultTxMaxAttempts = 20
|
||||
DefaultTxBaseDelay = 100 * time.Millisecond
|
||||
)
|
||||
|
||||
type jsonWrapper[T any] struct {
|
||||
@ -65,6 +73,33 @@ func key(parts ...string) string {
|
||||
return strings.Join(parts, ":")
|
||||
}
|
||||
|
||||
func WithRetry(ctx context.Context, client redis.UniversalClient, key string, fn func(ctx context.Context, tx *redis.Tx) error, maxAttempts int, baseDelay time.Duration) error {
|
||||
var err error
|
||||
|
||||
delay := baseDelay
|
||||
|
||||
for attempt := 0; attempt < maxAttempts; attempt++ {
|
||||
if err = WithTx(ctx, client, key, fn); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
logger.Debug(ctx, "redis transaction failed", logger.E(err))
|
||||
|
||||
if errors.Is(err, redis.TxFailedErr) {
|
||||
logger.Debug(ctx, "retrying redis transaction", logger.F("attempts", attempt), logger.F("delay", delay))
|
||||
time.Sleep(delay)
|
||||
delay = delay*2 + time.Duration(rand.Int63n(int64(baseDelay)))
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.WithStack(redis.TxFailedErr)
|
||||
}
|
||||
|
||||
func WithTx(ctx context.Context, client redis.UniversalClient, key string, fn func(ctx context.Context, tx *redis.Tx) error) error {
|
||||
txf := func(tx *redis.Tx) error {
|
||||
if err := fn(ctx, tx); err != nil {
|
||||
|
Reference in New Issue
Block a user