{"id":19572472,"url":"https://github.com/lestrrat-go/backoff","last_synced_at":"2025-05-15T18:02:11.921Z","repository":{"id":37444905,"uuid":"118608673","full_name":"lestrrat-go/backoff","owner":"lestrrat-go","description":"Backoff mechanics for Go","archived":false,"fork":false,"pushed_at":"2024-07-26T23:12:44.000Z","size":113,"stargazers_count":187,"open_issues_count":2,"forks_count":13,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-31T21:49:07.109Z","etag":null,"topics":["backoff"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lestrrat-go.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-23T12:39:18.000Z","updated_at":"2024-11-30T03:32:51.000Z","dependencies_parsed_at":"2024-12-15T18:02:10.876Z","dependency_job_id":null,"html_url":"https://github.com/lestrrat-go/backoff","commit_stats":{"total_commits":87,"total_committers":7,"mean_commits":"12.428571428571429","dds":"0.11494252873563215","last_synced_commit":"51026d9f5dca19324808822339487a1c36645a8c"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fbackoff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fbackoff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fbackoff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fbackoff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lestrrat-go","download_url":"https://codeload.github.com/lestrrat-go/backoff/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247737788,"owners_count":20987721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backoff"],"created_at":"2024-11-11T06:27:02.642Z","updated_at":"2025-04-07T22:10:34.008Z","avatar_url":"https://github.com/lestrrat-go.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# backoff ![](https://github.com/lestrrat-go/backoff/workflows/CI/badge.svg) [![Go Reference](https://pkg.go.dev/badge/github.com/lestrrat-go/backoff/v2.svg)](https://pkg.go.dev/github.com/lestrrat-go/backoff/v2)\n\nIdiomatic backoff for Go\n\nThis library is an implementation of backoff algorithm for retrying operations\nin an idiomatic Go way. It respects `context.Context` natively, and the critical\nnotifications are done through *channel operations*, allowing you to write code \nthat is both more explicit and flexibile.\n\nFor a longer discussion, [please read this article](https://medium.com/@lestrrat/yak-shaving-with-backoff-libraries-in-go-80240f0aa30c)\n\n# IMPORT\n\n```go\nimport \"github.com/lestrrat-go/backoff/v2\"\n```\n\n# SYNOPSIS\n\n```go\nfunc ExampleExponential() {\n  p := backoff.Exponential(\n    backoff.WithMinInterval(time.Second),\n    backoff.WithMaxInterval(time.Minute),\n    backoff.WithJitterFactor(0.05),\n  )\n\n  flakyFunc := func(a int) (int, error) {\n    // silly function that only succeeds if the current call count is\n    // divisible by either 3 or 5 but not both\n    switch {\n    case a%15 == 0:\n      return 0, errors.New(`invalid`)\n    case a%3 == 0 || a%5 == 0:\n      return a, nil\n    }\n    return 0, errors.New(`invalid`)\n  }\n\n  ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\n  defer cancel()\n\n  retryFunc := func(v int) (int, error) {\n    b := p.Start(ctx)\n    for backoff.Continue(b) {\n      x, err := flakyFunc(v)\n      if err == nil {\n        return x, nil\n      }\n    }\n    return 0, errors.New(`failed to get value`)\n  }\n\n  retryFunc(15)\n}\n```\n\n# POLICIES\n\nPolicy objects describe a backoff policy, and are factories to create backoff Controller objects.\nController objects does the actual coordination.\nCreate a new controller for each invocation of a backoff enabled operation.\nThis way the controller object is protected from concurrent access (if you have one) and can easily be discarded\n\n## Null\n\nA null policy means there's no backoff. \n\nFor example, if you were to support both using and not using a backoff in your code you can say\n\n```go\n  var p backoff.Policy\n  if useBackoff {\n    p = backoff.Exponential(...)\n  } else {\n    p = backoff.Null()\n  }\n  c := p.Start(ctx)\n  for backoff.Continue(c) {\n    if err := doSomething(); err != nil {\n      continue\n    }\n    return\n  }\n```\n\nInstead of\n\n```go\n  if useBackoff {\n    p := backoff.Exponential(...)\n    c := p.Start(ctx)\n    for backoff.Continue(c) {\n      if err := doSomething(); err != nil {\n        continue\n      }\n      return\n    }\n  } else {\n    if err := doSomething(); err != nil {\n      continue\n    }\n  }\n```\n\n## Constant\n\nA constant policy implements are backoff where the intervals are always the same\n\n## Exponential\n\nThis is the most \"common\" of the backoffs. Intervals between calls are spaced out such that as you keep retrying, the intervals keep increasing.\n\n# FAQ\n\n## I'm getting \"package github.com/lestrrat-go/backoff/v2: no Go files in /go/src/github.com/lestrrat-go/backoff/v2\"\n\nYou are using Go in GOPATH mode, which was the way before [Go Modules](https://blog.golang.org/using-go-modules) were introduced in Go 1.11 (Aug 2018).\nGOPATH has slowly been phased out, and in Go 1.14 onwards, Go Modules pretty much Just Work.\nGo 1.16 introduced more visible changes that forces users to be aware of the existance of go.mod files.\n\nThe short answer when you you get the above error is: **Migrate to using Go Modules**.\nThis is simple: All you need to do is to include a go.mod (and go.sum) file to your library or app.\n\nFor example, if you have previously been doing this:\n\n```\ngit clone git@github.com:myusername/myawesomeproject.git\ncd myawesomeproject\ngo get ./...\n```\n\nFirst include go.mod and go.sum in your repository:\n\n```\ngit clone git@github.com:myusername/myawesomeproject.git\ncd myawesomeproject\ngo mod init\ngo mod tidy\ngit add go.mod go.sum\ngit commit -m \"Add go.mod and go.sum\" -a\ngit push \n```\n\nThen from subsequent calls:\n\n```\ngit clone git@github.com:myusername/myawesomeproject.git\ncd myawesomeproject\ngo build # or go test, or go run, or whatever.\n```\n\nThis will tell go to respect tags, and will automatically pick up the latest version of github.com/lestrrat-go/backoff\n\nIf you really can't do this, then the quick and dirty workaround is to just copy the files over to /v2 directory of this library\n\n```\nBACKOFF=github.com/lestrrat-go/backoff\ngo get github.com/lestrrat-go/backoff\nif [[ if ! -d \"$GOPATH/src/$BACKOFF/v2\" ]]; then\n  mkdir \"$GOPATH/src/$BACKOFF/v2\" # just to make sure it exists\nfi\ncp \"$GOPATH/src/$BACKOFF/*.go\" \"$GOPATH/src/$BACKOFF/v2\"\n\ngit clone git@github.com:myusername/myawesomeproject.git\ncd myawesomeproject\ngo get ./...\n```\n\n## Why won't you just add the files in /v2?\n\nBecause it's hard to maintain multiple sources of truth. Sorry, I don't get paid to do this.\nI will not hold anything against you if you decided to fork this to your repository, and move files to your own /v2 directory.\nThen, if you have a go.mod in your app, you can just do\n\n```\ngo mod edit -replace github.com/lestrrat-go/backoff/v2=github.com/myusername/myawesomemfork/v2\n```\n\nOh, wait, then you already have go.mod, so this is a non-issue. \n\n...Yeah, just migrate to using go modules, please?\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flestrrat-go%2Fbackoff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flestrrat-go%2Fbackoff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flestrrat-go%2Fbackoff/lists"}