├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── _examples └── main.go ├── retry.go └── retry_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.8.5 4 | - 1.9.2 5 | - tip 6 | matrix: 7 | allow_failures: 8 | - go: tip 9 | 10 | notifications: 11 | email: 12 | recipients: dean.karn@gmail.com 13 | on_success: change 14 | on_failure: always 15 | 16 | before_install: 17 | - go get -u github.com/go-playground/overalls 18 | - go get -u github.com/mattn/goveralls 19 | - go get -u golang.org/x/tools/cmd/cover 20 | - go get -u github.com/golang/lint/golint 21 | - go get -u github.com/gordonklaus/ineffassign 22 | - go get -u github.com/client9/misspell/cmd/misspell 23 | 24 | before_script: 25 | - go vet ./... 26 | 27 | script: 28 | - gofmt -d -s . 29 | - golint ./... 30 | - ineffassign ./ 31 | - find . -type f | xargs misspell -source=text 32 | - go test -v ./... 33 | - go test -race 34 | 35 | after_success: | 36 | [ $TRAVIS_GO_VERSION = 1.9.2 ] && 37 | overalls -project="github.com/go-playground/retry" -covermode=count -ignore=.git,examples -debug && 38 | goveralls -coverprofile=overalls.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Go Playground 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Retry library 2 | ============= 3 | ![Project status](https://img.shields.io/badge/version-1.0.0-green.svg) 4 | [![Build Status](https://travis-ci.org/go-playground/retry.svg?branch=master)](https://travis-ci.org/go-playground/retry) 5 | [![Coverage Status](https://coveralls.io/repos/github/go-playground/retry/badge.svg?branch=master)](https://coveralls.io/github/go-playground/retry?branch=master) 6 | [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/retry)](https://goreportcard.com/report/github.com/go-playground/retry) 7 | [![GoDoc](https://godoc.org/github.com/go-playground/retry?status.svg)](https://godoc.org/github.com/go-playground/retry) 8 | ![License](https://img.shields.io/dub/l/vibe-d.svg) 9 | 10 | Retry library provides a set of standardized common components and abstracts away some code that normally is duplicated. 11 | My motivation is not to reinvent the wheel but to standardize a set of components for reuse in other libraries. 12 | 13 | Example 14 | ------------ 15 | ```go 16 | package main 17 | 18 | import ( 19 | "errors" 20 | "fmt" 21 | 22 | "github.com/go-playground/retry" 23 | ) 24 | 25 | func main() { 26 | err := retry.Run(5, func() (bool, error) { 27 | return false, errors.New("ERR") 28 | }, 29 | func(attempt uint16, err error) { 30 | fmt.Printf("Attempt: %d Error: %s\n", attempt, err) 31 | }, 32 | ) 33 | if err != nil { 34 | panic(err) 35 | } 36 | } 37 | 38 | ``` 39 | 40 | Package Versioning 41 | --------------- 42 | I'm jumping on the vendoring bandwagon, you should vendor this package as I will not 43 | be creating different version with gopkg.in like allot of my other libraries. 44 | 45 | Why? because my time is spread pretty thin maintaining all of the libraries I have + LIFE, 46 | it is so freeing not to worry about it and will help me keep pouring out bigger and better 47 | things for you the community. 48 | 49 | License 50 | ------ 51 | Distributed under MIT License, please see license file in code for more details. 52 | -------------------------------------------------------------------------------- /_examples/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | 7 | "github.com/go-playground/retry" 8 | ) 9 | 10 | func main() { 11 | err := retry.Run(5, func() (bool, error) { 12 | return false, errors.New("ERR") 13 | }, 14 | func(attempt uint16, err error) { 15 | fmt.Printf("Attempt: %d Error: %s\n", attempt, err) 16 | }, 17 | ) 18 | if err != nil { 19 | panic(err) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /retry.go: -------------------------------------------------------------------------------- 1 | package retry 2 | 3 | // Fn is the retry function signature. 4 | type Fn func() (bail bool, err error) 5 | 6 | // NotifyFn defines a function that is called upon each failed attempt. 7 | type NotifyFn func(attempt uint16, err error) 8 | 9 | // Run retries the provided function the specified number of times 10 | func Run(max uint16, fn Fn, notifyFn NotifyFn) (err error) { 11 | var bail bool 12 | for i := uint16(1); i <= max; i++ { 13 | if bail, err = fn(); err == nil || bail { 14 | return 15 | } 16 | if notifyFn != nil { 17 | notifyFn(i, err) 18 | } 19 | } 20 | return 21 | } 22 | -------------------------------------------------------------------------------- /retry_test.go: -------------------------------------------------------------------------------- 1 | package retry 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | func TestRetry(t *testing.T) { 10 | err := Run(5, 11 | func() (bool, error) { 12 | return false, errors.New("ERR") 13 | }, 14 | func(attempt uint16, err error) { 15 | fmt.Printf("Attempt: %d Error: %s\n", attempt, err) 16 | }, 17 | ) 18 | if err == nil { 19 | t.Fatalf("Expected %v Got %s", nil, err) 20 | } 21 | } 22 | 23 | func TestRetryBail(t *testing.T) { 24 | var count uint 25 | err := Run(5, 26 | func() (bool, error) { 27 | count++ 28 | return true, errors.New("ERR") 29 | }, 30 | func(attempt uint16, err error) { 31 | fmt.Printf("Attempt: %d Error: %s\n", attempt, err) 32 | }, 33 | ) 34 | if err == nil { 35 | t.Fatalf("Expected %v Got %s", nil, err) 36 | } 37 | if count != 1 { 38 | t.Fatalf("Expected %v Got %d", 1, count) 39 | } 40 | } 41 | --------------------------------------------------------------------------------