From 8ebe5cf185e9f7d2beb3bf0d632ac36fbe501a68 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Mon, 2 Oct 2017 17:29:57 +0200 Subject: [PATCH 01/21] generate readme use makefile to test (ci) --- .travis.yml | 4 +- README.md | 187 +++++++++++++++++++++++++++++++------- appveyor.yml | 4 +- examples/http_get_test.go | 22 +++-- retry.go | 44 ++++++++- retry_test.go | 3 +- test.sh | 12 --- 7 files changed, 212 insertions(+), 64 deletions(-) delete mode 100755 test.sh diff --git a/.travis.yml b/.travis.yml index 79cf2ba..4849546 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,10 @@ go: - tip install: - - go get -t -v -d ./... + - make setup script: - - ./test.sh + - make ci after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/README.md b/README.md index 966632c..8e74a27 100644 --- a/README.md +++ b/README.md @@ -1,60 +1,177 @@ # retry -[![Linux Build Status](https://travis-ci.org/avast/retry-go.svg)](https://travis-ci.org/avast/retry-go) -[![Windows Build status](https://ci.appveyor.com/api/projects/status/fieg9gon3qlq0a9a?svg=true)](https://ci.appveyor.com/project/JaSei/retry-go) -[![Go Report Card](https://goreportcard.com/badge/github.com/avast/retry-go)](https://goreportcard.com/report/github.com/avast/retry-go) -[![GoDoc](https://godoc.org/github.com/avast/retry-go?status.svg)](http://godoc.org/github.com/avast/retry-go) +[![Release](https://img.shields.io/github/release/avast/retry-go.svg?style=flat-square)](https://github.com/avast/retry-go/releases/latest) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) +[![Travis](https://img.shields.io/travis/avast/retry-go.svg?style=flat-square)](https://travis-ci.org/avast/retry-go) +[![AppVeyor](https://ci.appveyor.com/api/projects/status/fieg9gon3qlq0a9a?svg=true)](https://ci.appveyor.com/project/JaSei/retry-go) +[![Go Report Card](https://goreportcard.com/badge/github.com/avast/retry-go?style=flat-square)](https://goreportcard.com/report/github.com/avast/retry-go) +[![GoDoc](https://godoc.org/github.com/avast/retry-go?status.svg&style=flat-square)](http://godoc.org/github.com/avast/retry-go) +[![codecov.io](https://codecov.io/github/avast/retry-go/coverage.svg?branch=master)](https://codecov.io/github/avast/retry-go?branch=master) [![Sourcegraph](https://sourcegraph.com/github.com/avast/retry-go/-/badge.svg)](https://sourcegraph.com/github.com/avast/retry-go?badge) -[![codecov.io](https://codecov.io/github/boennemann/badges/coverage.svg?branch=master)](https://codecov.io/github/avast/retry-go?branch=master) Simple library for retry mechanism -slightly inspired by [Try::Tiny::Retry](https://metacpan.org/pod/Try::Tiny::Retry) +slightly inspired by +[Try::Tiny::Retry](https://metacpan.org/pod/Try::Tiny::Retry) -## INSTALL && USE -To get the package, execute: +### SYNOPSIS +http get with retry: + + url := "http://example.com" + var body []byte + + err := retry.Retry( + func() error { + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + body, err = ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + return nil + }, + ) + + fmt.Println(body) + +[next examples](https://github.com/avast/retry-go/examples) + + +### SEE ALSO + +* [giantswarm/retry-go](https://github.com/giantswarm/retry-go) - slightly +complicated interface. + +* [sethgrid/pester](https://github.com/sethgrid/pester) - only http retry for +http calls with retries and backoff + +* [cenkalti/backoff](https://github.com/cenkalti/backoff) - Go port of the +exponential backoff algorithm from Google's HTTP Client Library for Java. Really +complicated interface. + +## Usage + +#### func Retry + +```go +func Retry(retryableFunction Retryable) error ``` -go get gopkg.in/avast/retry-go.v0 +Retry - simple retry + + url := "http://example.com" + var body []byte + + err := retry.Retry( + func() error { + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + body, err = ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + return nil + }, + ) + +#### func RetryCustom + +```go +func RetryCustom(retryableFunction Retryable, onRetryFunction OnRetry, opts RetryOpts) error ``` +RetryCustom - the most customizable retry is possible set OnRetry function +callback which are called each retry -To import this package, add the following line to your code: +#### func RetryWithOpts ```go -import "gopkg.in/avast/retry-go.v0" +func RetryWithOpts(retryableFunction Retryable, opts RetryOpts) error ``` +RetryWithOpts - customizable retry via RetryOpts -### EXAMPLE +#### type OnRetry -http get with retry: +```go +type OnRetry func(n uint, err error) +``` + +Function signature of OnRetry function n = count of tries + +#### type RetryOpts ```go -url := "http://example.com" -var body []byte +type RetryOpts struct { +} +``` -err := retry.Retry( - func() error { - resp, err := http.Get(url) - if err != nil { - return err - } - defer resp.Body.Close() - body, err = ioutil.ReadAll(resp.Body) - if err != nil { - return err - } +Struct for configure retry tries - count of tries delay - waiting time units - +waiting time unit (for tests purpose) - return nil - }, -) +#### func NewRetryOpts -fmt.Println(body) +```go +func NewRetryOpts() RetryOpts +``` +Create new RetryOpts struct with default values default tries are 10 default +delay are 1e5 default units are microsecond + +#### func (RetryOpts) Delay + +```go +func (opts RetryOpts) Delay(delay time.Duration) RetryOpts +``` +Delay setter + +#### func (RetryOpts) Tries + +```go +func (opts RetryOpts) Tries(tries uint) RetryOpts +``` +Tries setter + +#### func (RetryOpts) Units + +```go +func (opts RetryOpts) Units(timeUnit time.Duration) RetryOpts ``` +Units setter + +#### type Retryable + +```go +type Retryable func() error +``` + +Function signature of retryable function + +## Contributing + +Contributions are very much welcome. + +### Makefile + +Makefile provides several handy rules, like README.md `generator` , `setup` for prepare build/dev environment, `test`, `cover`, etc... + +Try `make help` for more information. + +### Before pull request + +please try: +* run tests (`make test`) +* run linter (`make lint`) +* if your IDE don't automaticaly do `go fmt`, run `go fmt` (`make fmt`) + +### README -[next examples](examples) +README.md are generate from template [.godocdown.tmpl](.godocdown.tmpl) and code documentation via [godocdown](https://github.com/robertkrimen/godocdown). -## SEE ALSO -* [giantswarm/retry-go](https://github.com/giantswarm/retry-go) - slightly complicated interface. -* [sethgrid/pester](https://github.com/sethgrid/pester) - only http retry for http calls with retries and backoff -* [cenkalti/backoff](https://github.com/cenkalti/backoff) - Go port of the exponential backoff algorithm from Google's HTTP Client Library for Java. Really complicated interface. +Never edit README.md direct, because your change will be lost. diff --git a/appveyor.yml b/appveyor.yml index 9807787..5c0fdd9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ platform: x64 install: - go version - go env - - go get -v -t + - make setup build_script: - - go test -v ./... + - make ci diff --git a/examples/http_get_test.go b/examples/http_get_test.go index b89c57e..0112284 100644 --- a/examples/http_get_test.go +++ b/examples/http_get_test.go @@ -1,11 +1,12 @@ package retry_test import ( - "github.com/avast/retry-go" - "github.com/stretchr/testify/assert" "io/ioutil" "net/http" "testing" + + "github.com/avast/retry-go" + "github.com/stretchr/testify/assert" ) func TestGet(t *testing.T) { @@ -15,16 +16,17 @@ func TestGet(t *testing.T) { err := retry.Retry( func() error { resp, err := http.Get(url) - if err != nil { - return err - } - defer resp.Body.Close() - body, err = ioutil.ReadAll(resp.Body) - if err != nil { - return err + + if err == nil { + defer func() { + if err := resp.Body.Close(); err != nil { + panic(err) + } + }() + body, err = ioutil.ReadAll(resp.Body) } - return nil + return err }, ) diff --git a/retry.go b/retry.go index fd35526..db906f6 100644 --- a/retry.go +++ b/retry.go @@ -1,5 +1,45 @@ -// Simple library for retry mechanism -// slightly inspired by https://metacpan.org/pod/Try::Tiny::Retry +/* +Simple library for retry mechanism + +slightly inspired by [Try::Tiny::Retry](https://metacpan.org/pod/Try::Tiny::Retry) + +SYNOPSIS + +http get with retry: + + url := "http://example.com" + var body []byte + + err := retry.Retry( + func() error { + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + body, err = ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + return nil + }, + ) + + fmt.Println(body) + +[next examples](https://github.com/avast/retry-go/examples) + + +SEE ALSO + +* [giantswarm/retry-go](https://github.com/giantswarm/retry-go) - slightly complicated interface. + +* [sethgrid/pester](https://github.com/sethgrid/pester) - only http retry for http calls with retries and backoff + +* [cenkalti/backoff](https://github.com/cenkalti/backoff) - Go port of the exponential backoff algorithm from Google's HTTP Client Library for Java. Really complicated interface. + +*/ package retry import ( diff --git a/retry_test.go b/retry_test.go index 772727e..cabde3e 100644 --- a/retry_test.go +++ b/retry_test.go @@ -2,9 +2,10 @@ package retry import ( "errors" - "github.com/stretchr/testify/assert" "testing" "time" + + "github.com/stretchr/testify/assert" ) func TestCustom(t *testing.T) { diff --git a/test.sh b/test.sh deleted file mode 100755 index 88c4e8b..0000000 --- a/test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -echo "" > coverage.txt - -for d in $(go list ./... | grep -v vendor); do - go test -v -race -coverprofile=profile.out -covermode=atomic $d - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done From 8965d63135555d927ee4fb8fbd2ba76aeb57bcdb Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 10:37:22 +0200 Subject: [PATCH 02/21] make in appveyor --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 5c0fdd9..fbbbcad 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,6 +8,7 @@ platform: x64 install: - go version - go env + - copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe - make setup build_script: From 6c9b803b6cb26fe4f00c1651e554ca6f9cd34ec9 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 11:09:03 +0200 Subject: [PATCH 03/21] make support in appveyour --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index fbbbcad..68906f5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,6 +9,7 @@ install: - go version - go env - copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe + - set PATH=%PATH%;c:\MinGW\bin - make setup build_script: From 9f817dc79f5ac4b4fa10005700deac4fe7de0024 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 11:29:36 +0200 Subject: [PATCH 04/21] makefile and readme template --- .godocdown.tmpl | 37 +++++++++++++++++++++++++++++++++++++ Makefile | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 .godocdown.tmpl create mode 100644 Makefile diff --git a/.godocdown.tmpl b/.godocdown.tmpl new file mode 100644 index 0000000..6873edf --- /dev/null +++ b/.godocdown.tmpl @@ -0,0 +1,37 @@ +# {{ .Name }} + +[![Release](https://img.shields.io/github/release/avast/retry-go.svg?style=flat-square)](https://github.com/avast/retry-go/releases/latest) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) +[![Travis](https://img.shields.io/travis/avast/retry-go.svg?style=flat-square)](https://travis-ci.org/avast/retry-go) +[![AppVeyor](https://ci.appveyor.com/api/projects/status/fieg9gon3qlq0a9a?svg=true)](https://ci.appveyor.com/project/JaSei/retry-go) +[![Go Report Card](https://goreportcard.com/badge/github.com/avast/retry-go?style=flat-square)](https://goreportcard.com/report/github.com/avast/retry-go) +[![GoDoc](https://godoc.org/github.com/avast/retry-go?status.svg&style=flat-square)](http://godoc.org/github.com/avast/retry-go) +[![codecov.io](https://codecov.io/github/avast/retry-go/coverage.svg?branch=master)](https://codecov.io/github/avast/retry-go?branch=master) +[![Sourcegraph](https://sourcegraph.com/github.com/avast/retry-go/-/badge.svg)](https://sourcegraph.com/github.com/avast/retry-go?badge) + +{{ .EmitSynopsis }} + +{{ .EmitUsage }} + +## Contributing + +Contributions are very much welcome. + +### Makefile + +Makefile provides several handy rules, like README.md `generator` , `setup` for prepare build/dev environment, `test`, `cover`, etc... + +Try `make help` for more information. + +### Before pull request + +please try: +* run tests (`make test`) +* run linter (`make lint`) +* if your IDE don't automaticaly do `go fmt`, run `go fmt` (`make fmt`) + +### README + +README.md are generate from template [.godocdown.tmpl](.godocdown.tmpl) and code documentation via [godocdown](https://github.com/robertkrimen/godocdown). + +Never edit README.md direct, because your change will be lost. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..77822ca --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +SOURCE_FILES?=$$(go list ./... | grep -v /vendor/) +TEST_PATTERN?=. +TEST_OPTIONS?= + +setup: ## Install all the build and lint dependencies + go get -u github.com/alecthomas/gometalinter + go get -u github.com/pierrre/gotestcover + go get -u golang.org/x/tools/cmd/cover + go get -u github.com/robertkrimen/godocdown/godocdown + gometalinter --install + +generate: ## Generate README.md + godocdown >| README.md + +test: generate ## Run all the tests + gotestcover $(TEST_OPTIONS) -covermode=atomic -coverprofile=coverage.txt $(SOURCE_FILES) -run $(TEST_PATTERN) -timeout=2m + +cover: test ## Run all the tests and opens the coverage report + go tool cover -html=coverage.txt + +fmt: ## gofmt and goimports all go files + find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofmt -w -s "$$file"; goimports -w "$$file"; done + +lint: ## Run all the linters + gometalinter --vendor --disable-all \ + --enable=deadcode \ + --enable=ineffassign \ + --enable=gosimple \ + --enable=staticcheck \ + --enable=gofmt \ + --enable=goimports \ + --enable=dupl \ + --enable=misspell \ + --enable=errcheck \ + --enable=vet \ + --deadline=10m \ + ./... + +ci: test lint ## Run all the tests and code checks + +build: + go build + +# Absolutely awesome: http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html +help: + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.DEFAULT_GOAL := build From 79b8246834fe852164d59ac8881fc8940c9ad7bf Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 11:34:27 +0200 Subject: [PATCH 05/21] go/bin to PATH --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 68906f5..7591d2c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,6 +10,7 @@ install: - go env - copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe - set PATH=%PATH%;c:\MinGW\bin + - set PATH=%PATH%;c:\go\bin - make setup build_script: From 187ff737a84b69b745574c0dbc2ed8534ce1d41d Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 11:37:57 +0200 Subject: [PATCH 06/21] go bin --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 7591d2c..4842936 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ install: - go env - copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe - set PATH=%PATH%;c:\MinGW\bin - - set PATH=%PATH%;c:\go\bin + - set PATH=%PATH%;%GOPATH%\bin;c:\go\bin - make setup build_script: From c3d6ee7281810af0edb10458b1fbdb2246e641a8 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 12:33:33 +0200 Subject: [PATCH 07/21] gobinaries used in appveyor --- appveyor.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 4842936..61fb5bf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,11 +6,12 @@ clone_folder: c:\go\src\github.com\avast\retry-go platform: x64 install: - - go version - - go env - copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe - set PATH=%PATH%;c:\MinGW\bin - set PATH=%PATH%;%GOPATH%\bin;c:\go\bin + - set GOBIN=%GOPATH%\bin + - go version + - go env - make setup build_script: From 98b2059e2161580d73ca816ee064ca169287295b Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 13:10:21 +0200 Subject: [PATCH 08/21] fix gopath --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 61fb5bf..d8aa388 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,6 +7,7 @@ platform: x64 install: - copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe + - set GOPATH=c:\go - set PATH=%PATH%;c:\MinGW\bin - set PATH=%PATH%;%GOPATH%\bin;c:\go\bin - set GOBIN=%GOPATH%\bin From a531ca63d7952bad7ccb7a5187c8932d576b115a Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 13:12:42 +0200 Subject: [PATCH 09/21] fix gopath --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index d8aa388..d70d141 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ platform: x64 install: - copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe - - set GOPATH=c:\go + - set GOPATH=C:\Users\appveyor\go - set PATH=%PATH%;c:\MinGW\bin - set PATH=%PATH%;%GOPATH%\bin;c:\go\bin - set GOBIN=%GOPATH%\bin From 028ff70234e8d47a1af90bae5a36d4c6cd50db74 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 13:15:27 +0200 Subject: [PATCH 10/21] fix missing dep in Makefile --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 77822ca..0ee5dac 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,9 @@ setup: ## Install all the build and lint dependencies go get -u github.com/pierrre/gotestcover go get -u golang.org/x/tools/cmd/cover go get -u github.com/robertkrimen/godocdown/godocdown + go get -u github.com/golang/dep/cmd/dep gometalinter --install + dep ensure generate: ## Generate README.md godocdown >| README.md From 0ef32a0a6f812a3cdf4f0b07cf8db8685bd4bf8c Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 15:44:49 +0200 Subject: [PATCH 11/21] dep support --- .gitignore | 7 +++++++ Gopkg.toml | 3 +++ 2 files changed, 10 insertions(+) create mode 100644 Gopkg.toml diff --git a/.gitignore b/.gitignore index a1338d6..c40eb23 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,10 @@ # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 .glide/ + +# dep +vendor/ +Gopkg.lock + +# cover +coverage.txt diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..cf8c9eb --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,3 @@ +[[constraint]] + name = "github.com/stretchr/testify" + version = "1.1.4" From 08bf80e9297d467993a64101be46405e344411de Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 15:50:27 +0200 Subject: [PATCH 12/21] fix appveyor build --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index d70d141..dc5234a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ version: "{build}" -clone_folder: c:\go\src\github.com\avast\retry-go +clone_folder: c:\Users\appveyor\go\src\github.com\avast\retry-go #os: Windows Server 2012 R2 platform: x64 From b3a4fbfeadb4c9dc5c1ec6c2d6aecec3c1aecc32 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 17:20:53 +0200 Subject: [PATCH 13/21] remove tip (is too slow) from travis dep is download from github via curl (go get of dep needs go 1.8+) --- .travis.yml | 5 +++-- Makefile | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4849546..a25812f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,13 @@ language: go go: - 1.2 -# - 1.3 + - 1.3 - 1.4 - 1.5 - 1.6 - 1.7 - - tip + - 1.8 + - 1.9 install: - make setup diff --git a/Makefile b/Makefile index 0ee5dac..2b93118 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,18 @@ SOURCE_FILES?=$$(go list ./... | grep -v /vendor/) TEST_PATTERN?=. TEST_OPTIONS?= +DEP?=$$(which dep) setup: ## Install all the build and lint dependencies go get -u github.com/alecthomas/gometalinter go get -u github.com/pierrre/gotestcover go get -u golang.org/x/tools/cmd/cover go get -u github.com/robertkrimen/godocdown/godocdown - go get -u github.com/golang/dep/cmd/dep gometalinter --install + @if [ "$(DEP)" = "" ]; then\ + curl -L https://github.com/golang/dep/releases/download/v0.3.1/dep-linux-amd64 >| dep;\ + chmod +x dep;\ + fi dep ensure generate: ## Generate README.md From 31169c695dd0a2ce93420e19e1395ddf6cebb081 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 17:34:05 +0200 Subject: [PATCH 14/21] makefile check os and download right dep version --- Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2b93118..f1fa9ca 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,12 @@ TEST_PATTERN?=. TEST_OPTIONS?= DEP?=$$(which dep) +ifeq ($(OS),Windows_NT) + DEP_VERS=dep-windows-amd64 +else + DEP_VERS=dep-linux-amd64 +else + setup: ## Install all the build and lint dependencies go get -u github.com/alecthomas/gometalinter go get -u github.com/pierrre/gotestcover @@ -10,7 +16,7 @@ setup: ## Install all the build and lint dependencies go get -u github.com/robertkrimen/godocdown/godocdown gometalinter --install @if [ "$(DEP)" = "" ]; then\ - curl -L https://github.com/golang/dep/releases/download/v0.3.1/dep-linux-amd64 >| dep;\ + curl -L https://github.com/golang/dep/releases/download/v0.3.1/$(DEP_VERS) >| dep;\ chmod +x dep;\ fi dep ensure From 0eee6d8f3c07bce7cdb528f2e496ecf803f950cc Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 17:35:27 +0200 Subject: [PATCH 15/21] fix makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f1fa9ca..1cc947c 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ ifeq ($(OS),Windows_NT) DEP_VERS=dep-windows-amd64 else DEP_VERS=dep-linux-amd64 -else +endif setup: ## Install all the build and lint dependencies go get -u github.com/alecthomas/gometalinter From 7b9133c9d0b49d3958f5cede4d7dbcfee48c64d1 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 17:41:33 +0200 Subject: [PATCH 16/21] fix metalinter --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 1cc947c..dedf57a 100644 --- a/Makefile +++ b/Makefile @@ -10,11 +10,11 @@ else endif setup: ## Install all the build and lint dependencies - go get -u github.com/alecthomas/gometalinter + go get -u gopkg.in/alecthomas/gometalinter.v1 go get -u github.com/pierrre/gotestcover go get -u golang.org/x/tools/cmd/cover go get -u github.com/robertkrimen/godocdown/godocdown - gometalinter --install + gometalinter.v1 --install @if [ "$(DEP)" = "" ]; then\ curl -L https://github.com/golang/dep/releases/download/v0.3.1/$(DEP_VERS) >| dep;\ chmod +x dep;\ @@ -34,7 +34,7 @@ fmt: ## gofmt and goimports all go files find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofmt -w -s "$$file"; goimports -w "$$file"; done lint: ## Run all the linters - gometalinter --vendor --disable-all \ + gometalinter.v1 --vendor --disable-all \ --enable=deadcode \ --enable=ineffassign \ --enable=gosimple \ From 03e80ae3fe23f0a976bcf95f5532c0dc2a3dbd06 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 17:53:01 +0200 Subject: [PATCH 17/21] fix of metalinter problem --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index dedf57a..9ac67c1 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,8 @@ else endif setup: ## Install all the build and lint dependencies + # fix of gopkg.in issue (https://github.com/niemeyer/gopkg/issues/50) + git config --global http.https://gopkg.in.followRedirects true go get -u gopkg.in/alecthomas/gometalinter.v1 go get -u github.com/pierrre/gotestcover go get -u golang.org/x/tools/cmd/cover From 93ed7e8b37fd4be1e191a51ab38faa121568dbe3 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 3 Oct 2017 18:02:40 +0200 Subject: [PATCH 18/21] fix download dep for linux --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9ac67c1..d36978e 100644 --- a/Makefile +++ b/Makefile @@ -18,8 +18,8 @@ setup: ## Install all the build and lint dependencies go get -u github.com/robertkrimen/godocdown/godocdown gometalinter.v1 --install @if [ "$(DEP)" = "" ]; then\ - curl -L https://github.com/golang/dep/releases/download/v0.3.1/$(DEP_VERS) >| dep;\ - chmod +x dep;\ + curl -L https://github.com/golang/dep/releases/download/v0.3.1/$(DEP_VERS) >| $$GOPATH/bin/dep;\ + chmod +x $$GOPATH/bin/dep;\ fi dep ensure From e06934d42b120e8a6fb6621c2cada9525a85cb63 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Thu, 19 Oct 2017 15:59:57 +0200 Subject: [PATCH 19/21] remove duplicite example --- README.md | 19 ------------------- retry.go | 19 ------------------- 2 files changed, 38 deletions(-) diff --git a/README.md b/README.md index 8e74a27..179462d 100644 --- a/README.md +++ b/README.md @@ -64,25 +64,6 @@ func Retry(retryableFunction Retryable) error ``` Retry - simple retry - url := "http://example.com" - var body []byte - - err := retry.Retry( - func() error { - resp, err := http.Get(url) - if err != nil { - return err - } - defer resp.Body.Close() - body, err = ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - - return nil - }, - ) - #### func RetryCustom ```go diff --git a/retry.go b/retry.go index db906f6..77d68e3 100644 --- a/retry.go +++ b/retry.go @@ -56,25 +56,6 @@ type Retryable func() error type OnRetry func(n uint, err error) // Retry - simple retry -// -// url := "http://example.com" -// var body []byte -// -// err := retry.Retry( -// func() error { -// resp, err := http.Get(url) -// if err != nil { -// return err -// } -// defer resp.Body.Close() -// body, err = ioutil.ReadAll(resp.Body) -// if err != nil { -// return err -// } -// -// return nil -// }, -// ) func Retry(retryableFunction Retryable) error { return RetryWithOpts(retryableFunction, NewRetryOpts()) } From b0f75555f116a8965e5cc1b302ad59e4ccecda90 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Thu, 19 Oct 2017 17:36:57 +0200 Subject: [PATCH 20/21] test go 1.5+ --- .travis.yml | 3 --- Makefile | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a25812f..9636ed9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,6 @@ language: go go: - - 1.2 - - 1.3 - - 1.4 - 1.5 - 1.6 - 1.7 diff --git a/Makefile b/Makefile index d36978e..18ccfb7 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,9 @@ TEST_PATTERN?=. TEST_OPTIONS?= DEP?=$$(which dep) +GO15VENDOREXPERIMENT=1 +export GO15VENDOREXPERIMENT + ifeq ($(OS),Windows_NT) DEP_VERS=dep-windows-amd64 else From 6fe0bd55a84fe7c00b575a07b3f41ca04ea72c5b Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 10 Nov 2017 13:51:56 +0100 Subject: [PATCH 21/21] * travis build 1.6+ * Error type implements error and (hashicorp) errwrap interface --- .travis.yml | 1 - Makefile | 3 --- README.md | 25 +++++++++++++++++++++++++ VERSION | 1 + retry.go | 29 ++++++++++++++++++++++------- retry_test.go | 2 +- 6 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 VERSION diff --git a/.travis.yml b/.travis.yml index 9636ed9..54003a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: go go: - - 1.5 - 1.6 - 1.7 - 1.8 diff --git a/Makefile b/Makefile index 18ccfb7..d36978e 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,6 @@ TEST_PATTERN?=. TEST_OPTIONS?= DEP?=$$(which dep) -GO15VENDOREXPERIMENT=1 -export GO15VENDOREXPERIMENT - ifeq ($(OS),Windows_NT) DEP_VERS=dep-windows-amd64 else diff --git a/README.md b/README.md index 179462d..9389257 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,31 @@ func RetryWithOpts(retryableFunction Retryable, opts RetryOpts) error ``` RetryWithOpts - customizable retry via RetryOpts +#### type Error + +```go +type Error []error +``` + +Error type represents list of errors in retry + +#### func (Error) Error + +```go +func (e Error) Error() string +``` +Error method return string representation of Error It is an implementation of +error interface + +#### func (Error) WrappedErrors + +```go +func (e Error) WrappedErrors() []error +``` +WrappedErrors returns the list of errors that this Error is wrapping. It is an +implementation of the errwrap.Wrapper interface so that multierror.Error can be +used with that library. + #### type OnRetry ```go diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..0d91a54 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.3.0 diff --git a/retry.go b/retry.go index 77d68e3..25664c1 100644 --- a/retry.go +++ b/retry.go @@ -39,6 +39,10 @@ SEE ALSO * [cenkalti/backoff](https://github.com/cenkalti/backoff) - Go port of the exponential backoff algorithm from Google's HTTP Client Library for Java. Really complicated interface. +* [rafaeljesus/retry-go](https://github.com/rafaeljesus/retry-go) - looks good, slightly similar as this package, don't have 'simple' `Retry` method + +* [matryer/try](https://github.com/matryer/try) - very popular package, nonintuitive interface (for me) + */ package retry @@ -71,7 +75,7 @@ func RetryWithOpts(retryableFunction Retryable, opts RetryOpts) error { func RetryCustom(retryableFunction Retryable, onRetryFunction OnRetry, opts RetryOpts) error { var n uint - errorLog := make(errorLog, opts.tries) + errorLog := make(Error, opts.tries) for n < opts.tries { err := retryableFunction() @@ -89,16 +93,27 @@ func RetryCustom(retryableFunction Retryable, onRetryFunction OnRetry, opts Retr n++ } - return fmt.Errorf("All (%d) retries fail:\n%s", opts.tries, errorLog) + return errorLog } -type errorLog []error +// Error type represents list of errors in retry +type Error []error -func (log errorLog) String() string { - logWithNumber := make([]string, len(log)) - for i, l := range log { +// Error method return string representation of Error +// It is an implementation of error interface +func (e Error) Error() string { + logWithNumber := make([]string, len(e)) + for i, l := range e { logWithNumber[i] = fmt.Sprintf("#%d: %s", i+1, l.Error()) } - return strings.Join(logWithNumber, "\n") + return fmt.Sprintf("All retries fail:\n%s", strings.Join(logWithNumber, "\n")) +} + +// WrappedErrors returns the list of errors that this Error is wrapping. +// It is an implementation of the `errwrap.Wrapper` interface +// in package [errwrap](https://github.com/hashicorp/errwrap) so that +// `retry.Error` can be used with that library. +func (e Error) WrappedErrors() []error { + return e } diff --git a/retry_test.go b/retry_test.go index cabde3e..e8b6ca6 100644 --- a/retry_test.go +++ b/retry_test.go @@ -17,7 +17,7 @@ func TestCustom(t *testing.T) { ) assert.Error(t, err) - expectedErrorFormat := `All (10) retries fail: + expectedErrorFormat := `All retries fail: #1: test #2: test #3: test