resort imports
This commit is contained in:
Generated
-12
@@ -9,17 +9,6 @@
|
||||
revision = "767c40d6a2e058483c25fa193e963a22da17236d"
|
||||
version = "v0.18.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:6f958db63973bc397ef72acacbd56e045b4a0160af1224d6eb0f20deb860c0cd"
|
||||
name = "git.tkginternal.com/commons/pkg/repeater"
|
||||
packages = [
|
||||
".",
|
||||
"strategy",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "a207227f9303dc677c4d9644f709ad1e29bd0940"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bff7b2530f02b143623e260c11df5cbf34e0faeaca6aa001a8be31f333518ca9"
|
||||
name = "github.com/PuerkitoBio/goquery"
|
||||
@@ -400,7 +389,6 @@
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"git.tkginternal.com/commons/pkg/repeater",
|
||||
"github.com/PuerkitoBio/goquery",
|
||||
"github.com/coreos/bbolt",
|
||||
"github.com/dgrijalva/jwt-go",
|
||||
|
||||
@@ -5,10 +5,11 @@ import (
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/bbolt"
|
||||
bolt "github.com/coreos/bbolt"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/go-pkgz/auth/avatar"
|
||||
"github.com/go-pkgz/mongo"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// AvatarCommand set of flags and command for avatar migration
|
||||
|
||||
@@ -12,14 +12,13 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/go-pkgz/auth/token"
|
||||
|
||||
bolt "github.com/coreos/bbolt"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/go-pkgz/auth"
|
||||
"github.com/go-pkgz/auth/avatar"
|
||||
"github.com/go-pkgz/auth/provider"
|
||||
"github.com/go-pkgz/auth/token"
|
||||
"github.com/go-pkgz/mongo"
|
||||
"github.com/go-pkgz/rest/cache"
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/render"
|
||||
|
||||
"github.com/go-pkgz/auth"
|
||||
R "github.com/go-pkgz/rest"
|
||||
"github.com/go-pkgz/rest/cache"
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/render"
|
||||
|
||||
R "github.com/go-pkgz/rest"
|
||||
"github.com/go-pkgz/rest/cache"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
@@ -19,10 +19,10 @@ import (
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/go-chi/cors"
|
||||
"github.com/go-chi/render"
|
||||
"github.com/go-pkgz/auth"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rakyll/statik/fs"
|
||||
|
||||
"github.com/go-pkgz/auth"
|
||||
R "github.com/go-pkgz/rest"
|
||||
"github.com/go-pkgz/rest/cache"
|
||||
"github.com/go-pkgz/rest/logger"
|
||||
|
||||
@@ -10,14 +10,14 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-pkgz/auth/token"
|
||||
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/render"
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
|
||||
"github.com/go-pkgz/auth/token"
|
||||
R "github.com/go-pkgz/rest"
|
||||
"github.com/go-pkgz/rest/cache"
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
|
||||
"github.com/umputun/remark/backend/app/rest"
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/render"
|
||||
|
||||
R "github.com/go-pkgz/rest"
|
||||
"github.com/go-pkgz/rest/cache"
|
||||
|
||||
|
||||
@@ -7,10 +7,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-pkgz/rest/cache"
|
||||
"github.com/gorilla/feeds"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/go-pkgz/rest/cache"
|
||||
|
||||
"github.com/umputun/remark/backend/app/rest"
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
)
|
||||
|
||||
@@ -9,8 +9,9 @@ import (
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/chi/middleware"
|
||||
R "github.com/go-pkgz/rest"
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
|
||||
R "github.com/go-pkgz/rest"
|
||||
)
|
||||
|
||||
// sslMode defines ssl mode for rest server
|
||||
|
||||
@@ -8,12 +8,12 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.tkginternal.com/commons/pkg/repeater"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/go-pkgz/repeater"
|
||||
|
||||
"github.com/umputun/remark/backend/app/rest"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@ import (
|
||||
|
||||
"github.com/globalsign/mgo"
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"github.com/go-pkgz/mongo"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/go-pkgz/mongo"
|
||||
)
|
||||
|
||||
// MongoStore implements admin.Store with mongo backend
|
||||
|
||||
@@ -5,10 +5,11 @@ import (
|
||||
|
||||
"github.com/globalsign/mgo"
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"github.com/go-pkgz/mongo"
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/go-pkgz/mongo"
|
||||
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,9 +5,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
|
||||
"github.com/google/uuid"
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
image: docker.tkginternal.com/system/buildimage-go:1.1-master
|
||||
|
||||
stages:
|
||||
- build
|
||||
|
||||
variables:
|
||||
PROJ: "repeater"
|
||||
GROUP: "commons/pkg"
|
||||
PKG: "git.tkginternal.com"
|
||||
|
||||
build_app:
|
||||
stage: build
|
||||
script:
|
||||
- mkdir -p /go/src/$PKG/$GROUP && cp -fR $CI_PROJECT_DIR /go/src/$PKG/$GROUP/$PROJ
|
||||
- mkdir -p $CI_PROJECT_DIR/target && ln -s $CI_PROJECT_DIR/target /go/src/$PKG/$GROUP/$PROJ/target
|
||||
- cd /go/src/$PKG/$GROUP/$PROJ
|
||||
- go get -v && go get -t $(go list -e ./... | grep -v vendor) && go test -v $(go list -e ./... | grep -v vendor)
|
||||
- gometalinter --exclude=test --vendored-linters --disable-all --vendor --enable=vet --enable=vetshadow --enable=golint --enable=ineffassign --enable=goconst --enable=gas --enable=staticcheck --enable=errcheck --deadline=120s ./...
|
||||
- go build -ldflags "-X main.revision=$REV" -o $CI_PROJECT_DIR/target/$PROJ
|
||||
- cd /go/src/$PKG/$GROUP/$PROJ && /script/coverage.sh
|
||||
tags:
|
||||
- gobuilder
|
||||
artifacts:
|
||||
paths:
|
||||
- target/
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
# Repeater
|
||||
|
||||
[](https://git.tkginternal.com/commons/pkg/repeater/commits/master)
|
||||
[](https://git.tkginternal.com/commons/pkg/repeater/commits/master)
|
||||
[](https://godoc.tkginternal.com/pkg/git.tkginternal.com/commons/pkg/repeater/)
|
||||
|
||||
|
||||
Package repeater call fun till it returns no error, up to repeat some number of iterations and delays defined by strategy.
|
||||
Repeats number and delays defined by strategy.Interface. Terminates immediately on err from provided, optional list of critical errors
|
||||
|
||||
## Install and update
|
||||
|
||||
`go get -u git.tkginternal.com/commons/pkg/repeater`
|
||||
|
||||
## How to use
|
||||
|
||||
New Repeater created by `New(strtg strategy.Interface)` or shortcut for defaults - `NewDefault(repeats int, delay time.Duration) *Repeater`.
|
||||
|
||||
To activate use `Do` method. Do repeats fun till no error. Predefined (optional) errors terminate immediately
|
||||
|
||||
`func (r Repeater) Do(fun func() error, errors ...error) (err error)`
|
||||
|
||||
### Repeating strategy
|
||||
|
||||
User can provide his own strategy implementing this interface:
|
||||
|
||||
```go
|
||||
type Interface interface {
|
||||
Start(ctx context.Context) chan struct{}
|
||||
}
|
||||
```
|
||||
|
||||
Returned channels used as "ticks", i.e. for each repeat (or initial) operation one read from this channel needed. Closing this channel indicates "done with retries". This is pretty much the same idea as `time.Timer` or `time.Tick` implements. Note - the first (technically not-repeated-yet) call won't happen **until something sent to the channel**. This is why typical strategy sends first "tick" prior to first wait/sleep.
|
||||
|
||||
Three mist common strategies provided by package and ready to use:
|
||||
1. **Fixed delay**, up to max number of attempts - `NewFixedDelay(repeats int, delay time.Duration)`.
|
||||
This is default strategy used by `repeater.NewDefault` constructor
|
||||
2. **BackOff** with jitter provides exponential backoff. It starts from 100ms interval and goes in steps with `last * math.Pow(factor, attempt)`. Optional jitter randomizes intervals a little bit. The strategy created by `NewBackoff(repeats int, factor float64, jitter bool)`. _Factor = 1 effectively makes this strategy fixed with 100ms delay._
|
||||
|
||||
3. **Once** strategy does not do any repeats and mainly useful for tests - `NewOnce()`
|
||||
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
// Package repeater call fun till it returns no error, up to repeat some number of iterations and delays defined by strategy.
|
||||
// Repeats number and delays defined by strategy.Interface. Terminates immediately on err from
|
||||
// provided, optional list of critical errors
|
||||
package repeater
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.tkginternal.com/commons/pkg/repeater/strategy"
|
||||
)
|
||||
|
||||
// Repeater is the main object, should be made by New or NewDefault, embeds strategy
|
||||
type Repeater struct {
|
||||
strategy.Interface
|
||||
}
|
||||
|
||||
// New repeater with a given strategy. If strategy=nil initializes with FixedDelay 5sec, 10 times.
|
||||
func New(strtg strategy.Interface) *Repeater {
|
||||
if strtg == nil {
|
||||
strtg = strategy.NewFixedDelay(10, time.Second*5)
|
||||
}
|
||||
result := Repeater{Interface: strtg}
|
||||
return &result
|
||||
}
|
||||
|
||||
// NewDefault makes repeater with FixedDelay strategy
|
||||
func NewDefault(repeats int, delay time.Duration) *Repeater {
|
||||
return New(strategy.NewFixedDelay(repeats, delay))
|
||||
}
|
||||
|
||||
// Do repeats fun till no error. Predefined (optional) errors terminate immediately
|
||||
func (r Repeater) Do(fun func() error, errors ...error) (err error) {
|
||||
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
defer cancelFunc() // ensure strategy's channel termination
|
||||
|
||||
inErrors := func(err error) bool {
|
||||
for _, e := range errors {
|
||||
if e == err {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
ch := r.Start(ctx) // channel of ticks-like events provided by strategy
|
||||
|
||||
// closed channel indicates completion or early termination, set by strategy
|
||||
for range ch {
|
||||
|
||||
if err = fun(); err == nil {
|
||||
return nil
|
||||
}
|
||||
if err != nil && inErrors(err) { //terminate on critical error from provided list
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
package strategy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Backoff implements Interface for exponential-backoff
|
||||
// it starts from 100ms and goes in steps with last * math.Pow(factor, attempt)
|
||||
// optional jitter randomize intervals a little bit.
|
||||
type Backoff struct {
|
||||
repeats int
|
||||
factor float64
|
||||
jitter bool
|
||||
}
|
||||
|
||||
// NewBackoff makes Backoff strategy with given factor and optional jitter
|
||||
func NewBackoff(repeats int, factor float64, jitter bool) Interface {
|
||||
if repeats == 0 {
|
||||
repeats = 1
|
||||
}
|
||||
if factor <= 0 {
|
||||
factor = 1
|
||||
}
|
||||
result := Backoff{repeats: repeats, factor: factor, jitter: jitter}
|
||||
return &result
|
||||
}
|
||||
|
||||
// Start returns channel, similar to time.Timer
|
||||
// then publishing signals to channel ch for retries attempt. Closed ch indicates "done" event
|
||||
// consumer (repeater) should stop it explicitly after completion
|
||||
func (b *Backoff) Start(ctx context.Context) (ch chan struct{}) {
|
||||
ch = make(chan struct{})
|
||||
go func() {
|
||||
defer close(ch)
|
||||
rnd := rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
|
||||
minDelay := 100 * time.Millisecond // starts 100ms
|
||||
for i := 0; i < b.repeats; i++ {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
ch <- struct{}{}
|
||||
delay := float64(minDelay) * math.Pow(b.factor, float64(i))
|
||||
if b.jitter {
|
||||
delay = rnd.Float64()*(float64(2*minDelay)) + (delay - float64(minDelay))
|
||||
}
|
||||
// log.Printf("%v", time.Duration(delay))
|
||||
time.Sleep(time.Duration(delay))
|
||||
}
|
||||
}
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
package strategy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// FixedDelay implements Interface for fixed intervals up to max repeats
|
||||
type FixedDelay struct {
|
||||
repeats int
|
||||
delay time.Duration
|
||||
}
|
||||
|
||||
// NewFixedDelay makes a Interface
|
||||
func NewFixedDelay(repeats int, delay time.Duration) Interface {
|
||||
if repeats == 0 {
|
||||
repeats = 1
|
||||
}
|
||||
result := FixedDelay{repeats: repeats, delay: delay}
|
||||
return &result
|
||||
}
|
||||
|
||||
// Start returns channel, similar to time.Timer
|
||||
// then publishing signals to channel ch for retries attempt.
|
||||
// can be terminated (canceled) via context.
|
||||
func (s *FixedDelay) Start(ctx context.Context) (ch chan struct{}) {
|
||||
ch = make(chan struct{})
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for i := 0; i < s.repeats; i++ {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
ch <- struct{}{}
|
||||
time.Sleep(s.delay)
|
||||
}
|
||||
}
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
// Package strategy defines repeater's strategy and implements some. Strategy result
|
||||
// is channel acting like time.Timer ot time.Tick
|
||||
package strategy
|
||||
|
||||
import "context"
|
||||
|
||||
// Interface for repeats strategy. Returns channel with ticks
|
||||
type Interface interface {
|
||||
Start(ctx context.Context) chan struct{}
|
||||
}
|
||||
|
||||
// Once strategy eliminate repeats and makes a single try only
|
||||
type Once struct{}
|
||||
|
||||
// NewOnce makes no-repeat strategy
|
||||
func NewOnce() Interface {
|
||||
return &Once{}
|
||||
}
|
||||
|
||||
// Start returns closed channel with a single element to prevent any repeats
|
||||
func (s *Once) Start(ctx context.Context) (ch chan struct{}) {
|
||||
ch = make(chan struct{})
|
||||
go func() {
|
||||
ch <- struct{}{}
|
||||
close(ch)
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
Reference in New Issue
Block a user