Skip to content

Today I learned

Learn something new every day

Menu
  • Home
  • About
  • Hello World! and Why I Started This Blog
Menu

How to Retry Like a Boss

Posted on 07/02/202206/02/2022 by Sagi Rosenthal

Today I learned How to retry like a boss. And the good part – K8s already did it for you.

func OnError(backoff wait.Backoff, retriable func(error) bool, fn func() error) error

Simple code that allows you to run fn and retry over and over until a certain condition occurs. let’s say you want to poll for your remote service and sometimes this poll call fails:

func IsServiceStatusOk(addr string) (bool, error) {
    svc := NewServiceConnection(addr)
    status, err := svc.GetStatus()
    if err != nil {
        return false, err
    }
    return status == statuscodes.Ok, nil
}

it may fail due to a bad status code, or due to an error in svc.GetStatus() call. Let’s just say that whatever error you are getting you’ll want to retry it, except for io.ErrClosedPipe – saying you need to re-open the connection so there is no use in trying again. here is a translation to code:

func shouldRetry(addr string) (err error) bool {
    if err == io.ErrClosedPipe {
        return false    
    }
    return true
}

the next step is to decide what is your retry strategy. You don’t want to blast the service with status checks it will consume the CPU for you and might cause DoS for the other side. The default backoff strategy of k8s is this:

var DefaultRetry = wait.Backoff{
	Steps:    4,
	Duration: 10 * time.Millisecond,
	Factor:   5.0,
	Jitter:   0.1,
}

feel free to further read the docs about how it is calculated but if the first attempt is in t=0 the next attempts will be in t=:

  • 50ms +1ms
  • 250ms +5ms
  • 1250ms +25ms

The + value marks a max random additional wait.

So the final retry code will look something like this

retry.OnError(retry.DefaultBackoff,shouldRetry,func() error {
    ok, err := IsServiceStatusOk(myAddr)
    if err != nil {
        return err
    }
    return fmt.Errorf("status is not ok")
})

That’s it! for further reading see:
Kubernetes retry go package: https://pkg.go.dev/k8s.io/client-go/util/retry
Kubernetes wait package: https://pkg.go.dev/k8s.io/apimachinery/pkg/util/wait

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

CAPTCHA


Recent Posts

  • How to Sell Stuff Online
  • How to Make Your Kubernetes Dev Cycle Faster
  • How To Be A Valuable Team Member
  • Don’t Make, Go Generate It
  • Why You Should Monkey Patch Your Next Unit-Test

Archives

  • July 2023
  • April 2023
  • January 2023
  • November 2022
  • August 2022
  • July 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022

Categories

  • Go
  • Learning
  • Software Utilities
Join the updates channel
© 2026 Today I learned | Powered by Minimalist Blog WordPress Theme