fix: retry caldav init at startup
This commit is contained in:
parent
352dfcf2b6
commit
b8fde634b5
1
go.mod
1
go.mod
@ -3,6 +3,7 @@ module domogeek
|
|||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/avast/retry-go v2.7.0+incompatible
|
||||||
github.com/dolanor/caldav-go v0.2.1
|
github.com/dolanor/caldav-go v0.2.1
|
||||||
github.com/hellofresh/health-go/v4 v4.5.0
|
github.com/hellofresh/health-go/v4 v4.5.0
|
||||||
github.com/prometheus/client_golang v1.12.1
|
github.com/prometheus/client_golang v1.12.1
|
||||||
|
2
go.sum
2
go.sum
@ -39,6 +39,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
|||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||||
|
github.com/avast/retry-go v2.7.0+incompatible h1:XaGnzl7gESAideSjr+I8Hki/JBi+Yb9baHlMRPeSC84=
|
||||||
|
github.com/avast/retry-go v2.7.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
|
@ -2,6 +2,7 @@ package calendar
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/avast/retry-go"
|
||||||
"github.com/dolanor/caldav-go/caldav"
|
"github.com/dolanor/caldav-go/caldav"
|
||||||
"github.com/dolanor/caldav-go/caldav/entities"
|
"github.com/dolanor/caldav-go/caldav/entities"
|
||||||
"github.com/dolanor/caldav-go/icalendar/components"
|
"github.com/dolanor/caldav-go/icalendar/components"
|
||||||
@ -28,10 +29,25 @@ func NewCaldav(caldavUrl, caldavPath string) (Caldav, error) {
|
|||||||
server, _ := caldav.NewServer(caldavUrl)
|
server, _ := caldav.NewServer(caldavUrl)
|
||||||
// create a CalDAV client to speak to the server
|
// create a CalDAV client to speak to the server
|
||||||
var client = caldav.NewClient(server, http.DefaultClient)
|
var client = caldav.NewClient(server, http.DefaultClient)
|
||||||
// start executing requests!
|
err := retry.Do(
|
||||||
err := client.ValidateServer(caldavPath)
|
func() error {
|
||||||
|
// start executing requests!
|
||||||
|
err := client.ValidateServer(caldavPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("bad caldav configuration, unable to validate connexion: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
retry.OnRetry(
|
||||||
|
func(n uint, err error) {
|
||||||
|
zap.S().Errorf("unable to validate caldav connection on retry %d: %v", n, err)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
retry.Attempts(0), // Infinite attempts
|
||||||
|
retry.DelayType(retry.BackOffDelay),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("bad caldav configuration, unable to validate connexion: %w", err)
|
return nil, fmt.Errorf("unable to validate caldav connection: %w", err)
|
||||||
}
|
}
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
21
vendor/github.com/avast/retry-go/.gitignore
generated
vendored
Normal file
21
vendor/github.com/avast/retry-go/.gitignore
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, build with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||||
|
.glide/
|
||||||
|
|
||||||
|
# dep
|
||||||
|
vendor/
|
||||||
|
Gopkg.lock
|
||||||
|
|
||||||
|
# cover
|
||||||
|
coverage.txt
|
37
vendor/github.com/avast/retry-go/.godocdown.tmpl
generated
vendored
Normal file
37
vendor/github.com/avast/retry-go/.godocdown.tmpl
generated
vendored
Normal file
@ -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.
|
21
vendor/github.com/avast/retry-go/.travis.yml
generated
vendored
Normal file
21
vendor/github.com/avast/retry-go/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.7
|
||||||
|
- 1.8
|
||||||
|
- 1.9
|
||||||
|
- "1.10"
|
||||||
|
- 1.11
|
||||||
|
- 1.12
|
||||||
|
- 1.13
|
||||||
|
- 1.14
|
||||||
|
- 1.15
|
||||||
|
|
||||||
|
install:
|
||||||
|
- make setup
|
||||||
|
|
||||||
|
script:
|
||||||
|
- make ci
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
- bash <(curl -s https://codecov.io/bash)
|
3
vendor/github.com/avast/retry-go/Gopkg.toml
generated
vendored
Normal file
3
vendor/github.com/avast/retry-go/Gopkg.toml
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[[constraint]]
|
||||||
|
name = "github.com/stretchr/testify"
|
||||||
|
version = "1.1.4"
|
21
vendor/github.com/avast/retry-go/LICENSE
generated
vendored
Normal file
21
vendor/github.com/avast/retry-go/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2017 Avast
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
65
vendor/github.com/avast/retry-go/Makefile
generated
vendored
Normal file
65
vendor/github.com/avast/retry-go/Makefile
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
SOURCE_FILES?=$$(go list ./... | grep -v /vendor/)
|
||||||
|
TEST_PATTERN?=.
|
||||||
|
TEST_OPTIONS?=
|
||||||
|
DEP?=$$(which dep)
|
||||||
|
VERSION?=$$(cat VERSION)
|
||||||
|
LINTER?=$$(which golangci-lint)
|
||||||
|
LINTER_VERSION=1.15.0
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
DEP_VERS=dep-windows-amd64
|
||||||
|
LINTER_FILE=golangci-lint-$(LINTER_VERSION)-windows-amd64.zip
|
||||||
|
LINTER_UNPACK= >| app.zip; unzip -j app.zip -d $$GOPATH/bin; rm app.zip
|
||||||
|
else ifeq ($(OS), Darwin)
|
||||||
|
LINTER_FILE=golangci-lint-$(LINTER_VERSION)-darwin-amd64.tar.gz
|
||||||
|
LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --wildcards --strip 1 "**/golangci-lint"
|
||||||
|
else
|
||||||
|
DEP_VERS=dep-linux-amd64
|
||||||
|
LINTER_FILE=golangci-lint-$(LINTER_VERSION)-linux-amd64.tar.gz
|
||||||
|
LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --wildcards --strip 1 "**/golangci-lint"
|
||||||
|
endif
|
||||||
|
|
||||||
|
setup:
|
||||||
|
go get -u github.com/pierrre/gotestcover
|
||||||
|
go get -u golang.org/x/tools/cmd/cover
|
||||||
|
go get -u github.com/robertkrimen/godocdown/godocdown
|
||||||
|
@if [ "$(LINTER)" = "" ]; then\
|
||||||
|
curl -L https://github.com/golangci/golangci-lint/releases/download/v$(LINTER_VERSION)/$(LINTER_FILE) $(LINTER_UNPACK) ;\
|
||||||
|
chmod +x $$GOPATH/bin/golangci-lint;\
|
||||||
|
fi
|
||||||
|
@if [ "$(DEP)" = "" ]; then\
|
||||||
|
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
|
||||||
|
|
||||||
|
generate: ## Generate README.md
|
||||||
|
godocdown >| README.md
|
||||||
|
|
||||||
|
test: generate test_and_cover_report lint
|
||||||
|
|
||||||
|
test_and_cover_report:
|
||||||
|
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
|
||||||
|
golangci-lint run
|
||||||
|
|
||||||
|
ci: test_and_cover_report ## Run all the tests but no linters - use https://golangci.com integration instead
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build
|
||||||
|
|
||||||
|
release: ## Release new version
|
||||||
|
git tag | grep -q $(VERSION) && echo This version was released! Increase VERSION! || git tag $(VERSION) && git push origin $(VERSION) && git tag v$(VERSION) && git push origin v$(VERSION)
|
||||||
|
|
||||||
|
# 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
|
351
vendor/github.com/avast/retry-go/README.md
generated
vendored
Normal file
351
vendor/github.com/avast/retry-go/README.md
generated
vendored
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
# retry
|
||||||
|
|
||||||
|
[![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)
|
||||||
|
|
||||||
|
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.Do(
|
||||||
|
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/tree/master/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.
|
||||||
|
|
||||||
|
* [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)
|
||||||
|
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
1.0.2 -> 2.0.0
|
||||||
|
|
||||||
|
* argument of `retry.Delay` is final delay (no multiplication by `retry.Units`
|
||||||
|
anymore)
|
||||||
|
|
||||||
|
* function `retry.Units` are removed
|
||||||
|
|
||||||
|
* [more about this breaking change](https://github.com/avast/retry-go/issues/7)
|
||||||
|
|
||||||
|
0.3.0 -> 1.0.0
|
||||||
|
|
||||||
|
* `retry.Retry` function are changed to `retry.Do` function
|
||||||
|
|
||||||
|
* `retry.RetryCustom` (OnRetry) and `retry.RetryCustomWithOpts` functions are
|
||||||
|
now implement via functions produces Options (aka `retry.OnRetry`)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
var (
|
||||||
|
DefaultAttempts = uint(10)
|
||||||
|
DefaultDelay = 100 * time.Millisecond
|
||||||
|
DefaultMaxJitter = 100 * time.Millisecond
|
||||||
|
DefaultOnRetry = func(n uint, err error) {}
|
||||||
|
DefaultRetryIf = IsRecoverable
|
||||||
|
DefaultDelayType = CombineDelay(BackOffDelay, RandomDelay)
|
||||||
|
DefaultLastErrorOnly = false
|
||||||
|
DefaultContext = context.Background()
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func BackOffDelay
|
||||||
|
|
||||||
|
```go
|
||||||
|
func BackOffDelay(n uint, config *Config) time.Duration
|
||||||
|
```
|
||||||
|
BackOffDelay is a DelayType which increases delay between consecutive retries
|
||||||
|
|
||||||
|
#### func Do
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Do(retryableFunc RetryableFunc, opts ...Option) error
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func FixedDelay
|
||||||
|
|
||||||
|
```go
|
||||||
|
func FixedDelay(_ uint, config *Config) time.Duration
|
||||||
|
```
|
||||||
|
FixedDelay is a DelayType which keeps delay the same through all iterations
|
||||||
|
|
||||||
|
#### func IsRecoverable
|
||||||
|
|
||||||
|
```go
|
||||||
|
func IsRecoverable(err error) bool
|
||||||
|
```
|
||||||
|
IsRecoverable checks if error is an instance of `unrecoverableError`
|
||||||
|
|
||||||
|
#### func RandomDelay
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandomDelay(_ uint, config *Config) time.Duration
|
||||||
|
```
|
||||||
|
RandomDelay is a DelayType which picks a random delay up to config.maxJitter
|
||||||
|
|
||||||
|
#### func Unrecoverable
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Unrecoverable(err error) error
|
||||||
|
```
|
||||||
|
Unrecoverable wraps an error in `unrecoverableError` struct
|
||||||
|
|
||||||
|
#### type Config
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Config struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type DelayTypeFunc
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DelayTypeFunc func(n uint, config *Config) time.Duration
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func CombineDelay
|
||||||
|
|
||||||
|
```go
|
||||||
|
func CombineDelay(delays ...DelayTypeFunc) DelayTypeFunc
|
||||||
|
```
|
||||||
|
CombineDelay is a DelayType the combines all of the specified delays into a new
|
||||||
|
DelayTypeFunc
|
||||||
|
|
||||||
|
#### 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 in package
|
||||||
|
[errwrap](https://github.com/hashicorp/errwrap) so that `retry.Error` can be
|
||||||
|
used with that library.
|
||||||
|
|
||||||
|
#### type OnRetryFunc
|
||||||
|
|
||||||
|
```go
|
||||||
|
type OnRetryFunc func(n uint, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Function signature of OnRetry function n = count of attempts
|
||||||
|
|
||||||
|
#### type Option
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Option func(*Config)
|
||||||
|
```
|
||||||
|
|
||||||
|
Option represents an option for retry.
|
||||||
|
|
||||||
|
#### func Attempts
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Attempts(attempts uint) Option
|
||||||
|
```
|
||||||
|
Attempts set count of retry default is 10
|
||||||
|
|
||||||
|
#### func Context
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Context(ctx context.Context) Option
|
||||||
|
```
|
||||||
|
Context allow to set context of retry default are Background context
|
||||||
|
|
||||||
|
example of immediately cancellation (maybe it isn't the best example, but it describes behavior enough; I hope)
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
retry.Do(
|
||||||
|
func() error {
|
||||||
|
...
|
||||||
|
},
|
||||||
|
retry.Context(ctx),
|
||||||
|
)
|
||||||
|
|
||||||
|
#### func Delay
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Delay(delay time.Duration) Option
|
||||||
|
```
|
||||||
|
Delay set delay between retry default is 100ms
|
||||||
|
|
||||||
|
#### func DelayType
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DelayType(delayType DelayTypeFunc) Option
|
||||||
|
```
|
||||||
|
DelayType set type of the delay between retries default is BackOff
|
||||||
|
|
||||||
|
#### func LastErrorOnly
|
||||||
|
|
||||||
|
```go
|
||||||
|
func LastErrorOnly(lastErrorOnly bool) Option
|
||||||
|
```
|
||||||
|
return the direct last error that came from the retried function default is
|
||||||
|
false (return wrapped errors with everything)
|
||||||
|
|
||||||
|
#### func MaxDelay
|
||||||
|
|
||||||
|
```go
|
||||||
|
func MaxDelay(maxDelay time.Duration) Option
|
||||||
|
```
|
||||||
|
MaxDelay set maximum delay between retry does not apply by default
|
||||||
|
|
||||||
|
#### func MaxJitter
|
||||||
|
|
||||||
|
```go
|
||||||
|
func MaxJitter(maxJitter time.Duration) Option
|
||||||
|
```
|
||||||
|
MaxJitter sets the maximum random Jitter between retries for RandomDelay
|
||||||
|
|
||||||
|
#### func OnRetry
|
||||||
|
|
||||||
|
```go
|
||||||
|
func OnRetry(onRetry OnRetryFunc) Option
|
||||||
|
```
|
||||||
|
OnRetry function callback are called each retry
|
||||||
|
|
||||||
|
log each retry example:
|
||||||
|
|
||||||
|
retry.Do(
|
||||||
|
func() error {
|
||||||
|
return errors.New("some error")
|
||||||
|
},
|
||||||
|
retry.OnRetry(func(n uint, err error) {
|
||||||
|
log.Printf("#%d: %s\n", n, err)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
#### func RetryIf
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RetryIf(retryIf RetryIfFunc) Option
|
||||||
|
```
|
||||||
|
RetryIf controls whether a retry should be attempted after an error (assuming
|
||||||
|
there are any retry attempts remaining)
|
||||||
|
|
||||||
|
skip retry if special error example:
|
||||||
|
|
||||||
|
retry.Do(
|
||||||
|
func() error {
|
||||||
|
return errors.New("special error")
|
||||||
|
},
|
||||||
|
retry.RetryIf(func(err error) bool {
|
||||||
|
if err.Error() == "special error" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
By default RetryIf stops execution if the error is wrapped using
|
||||||
|
`retry.Unrecoverable`, so above example may also be shortened to:
|
||||||
|
|
||||||
|
retry.Do(
|
||||||
|
func() error {
|
||||||
|
return retry.Unrecoverable(errors.New("special error"))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
#### type RetryIfFunc
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RetryIfFunc func(error) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
Function signature of retry if function
|
||||||
|
|
||||||
|
#### type RetryableFunc
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RetryableFunc 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
|
||||||
|
|
||||||
|
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.
|
1
vendor/github.com/avast/retry-go/VERSION
generated
vendored
Normal file
1
vendor/github.com/avast/retry-go/VERSION
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
2.7.0
|
19
vendor/github.com/avast/retry-go/appveyor.yml
generated
vendored
Normal file
19
vendor/github.com/avast/retry-go/appveyor.yml
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
version: "{build}"
|
||||||
|
|
||||||
|
clone_folder: c:\Users\appveyor\go\src\github.com\avast\retry-go
|
||||||
|
|
||||||
|
#os: Windows Server 2012 R2
|
||||||
|
platform: x64
|
||||||
|
|
||||||
|
install:
|
||||||
|
- copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe
|
||||||
|
- set GOPATH=C:\Users\appveyor\go
|
||||||
|
- 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:
|
||||||
|
- make ci
|
193
vendor/github.com/avast/retry-go/options.go
generated
vendored
Normal file
193
vendor/github.com/avast/retry-go/options.go
generated
vendored
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
package retry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"math"
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Function signature of retry if function
|
||||||
|
type RetryIfFunc func(error) bool
|
||||||
|
|
||||||
|
// Function signature of OnRetry function
|
||||||
|
// n = count of attempts
|
||||||
|
type OnRetryFunc func(n uint, err error)
|
||||||
|
|
||||||
|
type DelayTypeFunc func(n uint, config *Config) time.Duration
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
attempts uint
|
||||||
|
delay time.Duration
|
||||||
|
maxDelay time.Duration
|
||||||
|
maxJitter time.Duration
|
||||||
|
onRetry OnRetryFunc
|
||||||
|
retryIf RetryIfFunc
|
||||||
|
delayType DelayTypeFunc
|
||||||
|
lastErrorOnly bool
|
||||||
|
context context.Context
|
||||||
|
|
||||||
|
maxBackOffN uint
|
||||||
|
}
|
||||||
|
|
||||||
|
// Option represents an option for retry.
|
||||||
|
type Option func(*Config)
|
||||||
|
|
||||||
|
// return the direct last error that came from the retried function
|
||||||
|
// default is false (return wrapped errors with everything)
|
||||||
|
func LastErrorOnly(lastErrorOnly bool) Option {
|
||||||
|
return func(c *Config) {
|
||||||
|
c.lastErrorOnly = lastErrorOnly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempts set count of retry
|
||||||
|
// default is 10
|
||||||
|
func Attempts(attempts uint) Option {
|
||||||
|
return func(c *Config) {
|
||||||
|
c.attempts = attempts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delay set delay between retry
|
||||||
|
// default is 100ms
|
||||||
|
func Delay(delay time.Duration) Option {
|
||||||
|
return func(c *Config) {
|
||||||
|
c.delay = delay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaxDelay set maximum delay between retry
|
||||||
|
// does not apply by default
|
||||||
|
func MaxDelay(maxDelay time.Duration) Option {
|
||||||
|
return func(c *Config) {
|
||||||
|
c.maxDelay = maxDelay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaxJitter sets the maximum random Jitter between retries for RandomDelay
|
||||||
|
func MaxJitter(maxJitter time.Duration) Option {
|
||||||
|
return func(c *Config) {
|
||||||
|
c.maxJitter = maxJitter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DelayType set type of the delay between retries
|
||||||
|
// default is BackOff
|
||||||
|
func DelayType(delayType DelayTypeFunc) Option {
|
||||||
|
return func(c *Config) {
|
||||||
|
c.delayType = delayType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BackOffDelay is a DelayType which increases delay between consecutive retries
|
||||||
|
func BackOffDelay(n uint, config *Config) time.Duration {
|
||||||
|
// 1 << 63 would overflow signed int64 (time.Duration), thus 62.
|
||||||
|
const max uint = 62
|
||||||
|
|
||||||
|
if config.maxBackOffN == 0 {
|
||||||
|
if config.delay <= 0 {
|
||||||
|
config.delay = 1
|
||||||
|
}
|
||||||
|
config.maxBackOffN = max - uint(math.Floor(math.Log2(float64(config.delay))))
|
||||||
|
}
|
||||||
|
|
||||||
|
if n > config.maxBackOffN {
|
||||||
|
n = config.maxBackOffN
|
||||||
|
}
|
||||||
|
return config.delay << n
|
||||||
|
}
|
||||||
|
|
||||||
|
// FixedDelay is a DelayType which keeps delay the same through all iterations
|
||||||
|
func FixedDelay(_ uint, config *Config) time.Duration {
|
||||||
|
return config.delay
|
||||||
|
}
|
||||||
|
|
||||||
|
// RandomDelay is a DelayType which picks a random delay up to config.maxJitter
|
||||||
|
func RandomDelay(_ uint, config *Config) time.Duration {
|
||||||
|
return time.Duration(rand.Int63n(int64(config.maxJitter)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CombineDelay is a DelayType the combines all of the specified delays into a new DelayTypeFunc
|
||||||
|
func CombineDelay(delays ...DelayTypeFunc) DelayTypeFunc {
|
||||||
|
const maxInt64 = uint64(math.MaxInt64)
|
||||||
|
|
||||||
|
return func(n uint, config *Config) time.Duration {
|
||||||
|
var total uint64
|
||||||
|
for _, delay := range delays {
|
||||||
|
total += uint64(delay(n, config))
|
||||||
|
if total > maxInt64 {
|
||||||
|
total = maxInt64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return time.Duration(total)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnRetry function callback are called each retry
|
||||||
|
//
|
||||||
|
// log each retry example:
|
||||||
|
//
|
||||||
|
// retry.Do(
|
||||||
|
// func() error {
|
||||||
|
// return errors.New("some error")
|
||||||
|
// },
|
||||||
|
// retry.OnRetry(func(n uint, err error) {
|
||||||
|
// log.Printf("#%d: %s\n", n, err)
|
||||||
|
// }),
|
||||||
|
// )
|
||||||
|
func OnRetry(onRetry OnRetryFunc) Option {
|
||||||
|
return func(c *Config) {
|
||||||
|
c.onRetry = onRetry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetryIf controls whether a retry should be attempted after an error
|
||||||
|
// (assuming there are any retry attempts remaining)
|
||||||
|
//
|
||||||
|
// skip retry if special error example:
|
||||||
|
//
|
||||||
|
// retry.Do(
|
||||||
|
// func() error {
|
||||||
|
// return errors.New("special error")
|
||||||
|
// },
|
||||||
|
// retry.RetryIf(func(err error) bool {
|
||||||
|
// if err.Error() == "special error" {
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
// return true
|
||||||
|
// })
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// By default RetryIf stops execution if the error is wrapped using `retry.Unrecoverable`,
|
||||||
|
// so above example may also be shortened to:
|
||||||
|
//
|
||||||
|
// retry.Do(
|
||||||
|
// func() error {
|
||||||
|
// return retry.Unrecoverable(errors.New("special error"))
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
func RetryIf(retryIf RetryIfFunc) Option {
|
||||||
|
return func(c *Config) {
|
||||||
|
c.retryIf = retryIf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context allow to set context of retry
|
||||||
|
// default are Background context
|
||||||
|
//
|
||||||
|
// example of immediately cancellation (maybe it isn't the best example, but it describes behavior enough; I hope)
|
||||||
|
// ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
// cancel()
|
||||||
|
//
|
||||||
|
// retry.Do(
|
||||||
|
// func() error {
|
||||||
|
// ...
|
||||||
|
// },
|
||||||
|
// retry.Context(ctx),
|
||||||
|
// )
|
||||||
|
func Context(ctx context.Context) Option {
|
||||||
|
return func(c *Config) {
|
||||||
|
c.context = ctx
|
||||||
|
}
|
||||||
|
}
|
219
vendor/github.com/avast/retry-go/retry.go
generated
vendored
Normal file
219
vendor/github.com/avast/retry-go/retry.go
generated
vendored
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
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.Do(
|
||||||
|
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/tree/master/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.
|
||||||
|
|
||||||
|
* [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)
|
||||||
|
|
||||||
|
BREAKING CHANGES
|
||||||
|
|
||||||
|
1.0.2 -> 2.0.0
|
||||||
|
|
||||||
|
* argument of `retry.Delay` is final delay (no multiplication by `retry.Units` anymore)
|
||||||
|
|
||||||
|
* function `retry.Units` are removed
|
||||||
|
|
||||||
|
* [more about this breaking change](https://github.com/avast/retry-go/issues/7)
|
||||||
|
|
||||||
|
|
||||||
|
0.3.0 -> 1.0.0
|
||||||
|
|
||||||
|
* `retry.Retry` function are changed to `retry.Do` function
|
||||||
|
|
||||||
|
* `retry.RetryCustom` (OnRetry) and `retry.RetryCustomWithOpts` functions are now implement via functions produces Options (aka `retry.OnRetry`)
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
package retry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Function signature of retryable function
|
||||||
|
type RetryableFunc func() error
|
||||||
|
|
||||||
|
var (
|
||||||
|
DefaultAttempts = uint(10)
|
||||||
|
DefaultDelay = 100 * time.Millisecond
|
||||||
|
DefaultMaxJitter = 100 * time.Millisecond
|
||||||
|
DefaultOnRetry = func(n uint, err error) {}
|
||||||
|
DefaultRetryIf = IsRecoverable
|
||||||
|
DefaultDelayType = CombineDelay(BackOffDelay, RandomDelay)
|
||||||
|
DefaultLastErrorOnly = false
|
||||||
|
DefaultContext = context.Background()
|
||||||
|
)
|
||||||
|
|
||||||
|
func Do(retryableFunc RetryableFunc, opts ...Option) error {
|
||||||
|
var n uint
|
||||||
|
|
||||||
|
//default
|
||||||
|
config := &Config{
|
||||||
|
attempts: DefaultAttempts,
|
||||||
|
delay: DefaultDelay,
|
||||||
|
maxJitter: DefaultMaxJitter,
|
||||||
|
onRetry: DefaultOnRetry,
|
||||||
|
retryIf: DefaultRetryIf,
|
||||||
|
delayType: DefaultDelayType,
|
||||||
|
lastErrorOnly: DefaultLastErrorOnly,
|
||||||
|
context: DefaultContext,
|
||||||
|
}
|
||||||
|
|
||||||
|
//apply opts
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := config.context.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorLog Error
|
||||||
|
if !config.lastErrorOnly {
|
||||||
|
errorLog = make(Error, config.attempts)
|
||||||
|
} else {
|
||||||
|
errorLog = make(Error, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastErrIndex := n
|
||||||
|
for n < config.attempts {
|
||||||
|
err := retryableFunc()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
errorLog[lastErrIndex] = unpackUnrecoverable(err)
|
||||||
|
|
||||||
|
if !config.retryIf(err) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
config.onRetry(n, err)
|
||||||
|
|
||||||
|
// if this is last attempt - don't wait
|
||||||
|
if n == config.attempts-1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
delayTime := config.delayType(n, config)
|
||||||
|
if config.maxDelay > 0 && delayTime > config.maxDelay {
|
||||||
|
delayTime = config.maxDelay
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-time.After(delayTime):
|
||||||
|
case <-config.context.Done():
|
||||||
|
return config.context.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
n++
|
||||||
|
if !config.lastErrorOnly {
|
||||||
|
lastErrIndex = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.lastErrorOnly {
|
||||||
|
return errorLog[lastErrIndex]
|
||||||
|
}
|
||||||
|
return errorLog
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error type represents list of errors in retry
|
||||||
|
type Error []error
|
||||||
|
|
||||||
|
// Error method return string representation of Error
|
||||||
|
// It is an implementation of error interface
|
||||||
|
func (e Error) Error() string {
|
||||||
|
logWithNumber := make([]string, lenWithoutNil(e))
|
||||||
|
for i, l := range e {
|
||||||
|
if l != nil {
|
||||||
|
logWithNumber[i] = fmt.Sprintf("#%d: %s", i+1, l.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("All attempts fail:\n%s", strings.Join(logWithNumber, "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func lenWithoutNil(e Error) (count int) {
|
||||||
|
for _, v := range e {
|
||||||
|
if v != nil {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
type unrecoverableError struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unrecoverable wraps an error in `unrecoverableError` struct
|
||||||
|
func Unrecoverable(err error) error {
|
||||||
|
return unrecoverableError{err}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsRecoverable checks if error is an instance of `unrecoverableError`
|
||||||
|
func IsRecoverable(err error) bool {
|
||||||
|
_, isUnrecoverable := err.(unrecoverableError)
|
||||||
|
return !isUnrecoverable
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackUnrecoverable(err error) error {
|
||||||
|
if unrecoverable, isUnrecoverable := err.(unrecoverableError); isUnrecoverable {
|
||||||
|
return unrecoverable.error
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
3
vendor/modules.txt
vendored
3
vendor/modules.txt
vendored
@ -1,3 +1,6 @@
|
|||||||
|
# github.com/avast/retry-go v2.7.0+incompatible
|
||||||
|
## explicit
|
||||||
|
github.com/avast/retry-go
|
||||||
# github.com/beorn7/perks v1.0.1
|
# github.com/beorn7/perks v1.0.1
|
||||||
## explicit; go 1.11
|
## explicit; go 1.11
|
||||||
github.com/beorn7/perks/quantile
|
github.com/beorn7/perks/quantile
|
||||||
|
Loading…
Reference in New Issue
Block a user