Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaime Martinez <jmartinez@gitlab.com>2020-07-27 05:30:13 +0300
committerJaime Martinez <jmartinez@gitlab.com>2020-08-07 08:12:40 +0300
commit0ee194529b9c7b3d8a2d8859a24016e7a4d21a1d (patch)
tree1844856540d605ae098e5f609a78955a9e9dfe7f /internal/source/gitlab
parenta3b311f1522a756997a88aa3dabdf1c46acb0cfa (diff)
Use exponential backoff for polling
Introudce github.com/cenkalti/backoff/v4 library to use exponential backoff when polling the Status API.
Diffstat (limited to 'internal/source/gitlab')
-rw-r--r--internal/source/gitlab/gitlab.go4
-rw-r--r--internal/source/gitlab/gitlab_poll.go66
-rw-r--r--internal/source/gitlab/gitlab_poll_test.go15
3 files changed, 54 insertions, 31 deletions
diff --git a/internal/source/gitlab/gitlab.go b/internal/source/gitlab/gitlab.go
index 2635d864..67c4eb6b 100644
--- a/internal/source/gitlab/gitlab.go
+++ b/internal/source/gitlab/gitlab.go
@@ -8,6 +8,8 @@ import (
"strings"
"sync"
+ "github.com/cenkalti/backoff/v4"
+
"gitlab.com/gitlab-org/gitlab-pages/internal/domain"
"gitlab.com/gitlab-org/gitlab-pages/internal/request"
"gitlab.com/gitlab-org/gitlab-pages/internal/serving"
@@ -36,7 +38,7 @@ func New(config client.Config) (*Gitlab, error) {
mu: &sync.RWMutex{},
}
- go g.poll(defaultPollingMaxRetries, defaultPollingInterval)
+ go g.poll(backoff.DefaultInitialInterval, maxPollingTime)
// using nil for cache config will use the default values specified in internal/source/gitlab/cache/cache.go#12
return g, nil
diff --git a/internal/source/gitlab/gitlab_poll.go b/internal/source/gitlab/gitlab_poll.go
index 9fce7250..4e79bbf1 100644
--- a/internal/source/gitlab/gitlab_poll.go
+++ b/internal/source/gitlab/gitlab_poll.go
@@ -3,37 +3,57 @@ package gitlab
import (
"time"
+ "github.com/cenkalti/backoff/v4"
log "github.com/sirupsen/logrus"
)
const (
- // defaultPollingMaxRetries to be used by poll
- defaultPollingMaxRetries = 30
- // defaultPollingInterval to be used by poll
- defaultPollingInterval = time.Minute
+ // maxPollingTime is the maximum duration to try to call the Status API
+ maxPollingTime = 60 * time.Minute
)
-// poll tries to call the /internal/pages/status API endpoint once plus
-// `retries` every `interval`.
-// It updates the `isReady` value when successful.
+// Poll tries to call the /internal/pages/status API endpoint once plus
+// for `maxElapsedTime`
// TODO: Remove in https://gitlab.com/gitlab-org/gitlab/-/issues/218357
-func (g *Gitlab) poll(retries int, interval time.Duration) {
- var err error
- for i := 0; i <= retries; i++ {
+func (g *Gitlab) poll(interval, maxElapsedTime time.Duration) {
+ backOff := backoff.NewExponentialBackOff()
+ backOff.InitialInterval = interval
+ backOff.MaxElapsedTime = maxElapsedTime
+
+ op := func() error {
log.Info("Checking GitLab internal API availability")
- err = g.client.Status()
- if err == nil {
- log.Info("GitLab internal pages status API connected successfully")
- g.mu.Lock()
- g.isReady = true
- g.mu.Unlock()
-
- // return as soon as we connect to the API
- return
- }
-
- time.Sleep(interval)
+
+ return g.client.Status()
+ }
+
+ err := backoff.Retry(op, backOff)
+ if err != nil {
+ // Handle error.
+ log.WithError(err).Errorf("Failed to connect to the internal GitLab API after %.2fs", interval.Seconds())
+ return
}
- log.WithError(err).Errorf("Failed to connect to the internal GitLab API after %d tries every %.2fs", retries+1, interval.Seconds())
+ g.mu.Lock()
+ g.isReady = true
+ g.mu.Unlock()
+ log.Info("GitLab internal pages status API connected successfully")
+ //
+ // var err error
+ // for i := 0; i <= retries; i++ {
+ // log.Info("polling GitLab internal pages status API")
+ // err = g.checker.Status()
+ // if err == nil {
+ // log.Info("GitLab internal pages status API connected successfully")
+ // g.mu.Lock()
+ // g.isReady = true
+ // g.mu.Unlock()
+ //
+ // // return as soon as we connect to the API
+ // return
+ // }
+ //
+ // time.Sleep(interval)
+ // }
+ //
+ // log.WithError(err).Errorf("polling failed after %d tries every %.2fs", retries+1, interval.Seconds())
}
diff --git a/internal/source/gitlab/gitlab_poll_test.go b/internal/source/gitlab/gitlab_poll_test.go
index 01f13846..9a559015 100644
--- a/internal/source/gitlab/gitlab_poll_test.go
+++ b/internal/source/gitlab/gitlab_poll_test.go
@@ -17,31 +17,31 @@ func TestClient_Poll(t *testing.T) {
tests := []struct {
name string
retries int
- interval time.Duration
+ maxTime time.Duration
expectedFail bool
}{
{
name: "success_with_no_retry",
retries: 0,
- interval: 5 * time.Millisecond,
+ maxTime: 10 * time.Millisecond,
expectedFail: false,
},
{
name: "success_after_N_retries",
retries: 3,
- interval: 10 * time.Millisecond,
+ maxTime: 30 * time.Millisecond,
expectedFail: false,
},
{
name: "fail_with_no_retries",
retries: 0,
- interval: 5 * time.Millisecond,
+ maxTime: 10 * time.Millisecond,
expectedFail: true,
},
{
name: "fail_after_N_retries",
retries: 3,
- interval: 5 * time.Millisecond,
+ maxTime: 30 * time.Millisecond,
expectedFail: true,
},
}
@@ -64,10 +64,11 @@ func TestClient_Poll(t *testing.T) {
glClient := Gitlab{client: client, mu: &sync.RWMutex{}}
- glClient.poll(tt.retries, tt.interval)
+ glClient.poll(3*time.Millisecond, tt.maxTime)
if tt.expectedFail {
require.False(t, glClient.isReady)
- s := fmt.Sprintf("Failed to connect to the internal GitLab API after %d tries every %.2fs", tt.retries+1, tt.interval.Seconds())
+
+ s := fmt.Sprintf("\"Failed to connect to the internal GitLab API after %.2fs", tt.maxTime.Seconds())
require.Equal(t, s, hook.LastEntry().Message)
return
}