forked from Silverfish/proton-bridge
GODT-1468: Fix main windows status and add background context without retry.
This commit is contained in:
@ -34,6 +34,9 @@ type manager struct {
|
||||
locker sync.Locker
|
||||
connectionObservers []ConnectionObserver
|
||||
proxyDialer *ProxyTLSDialer
|
||||
|
||||
pingMutex *sync.RWMutex
|
||||
isPinging bool
|
||||
}
|
||||
|
||||
func New(cfg Config) Manager {
|
||||
@ -42,9 +45,11 @@ func New(cfg Config) Manager {
|
||||
|
||||
func newManager(cfg Config) *manager {
|
||||
m := &manager{
|
||||
cfg: cfg,
|
||||
rc: resty.New().EnableTrace(),
|
||||
locker: &sync.Mutex{},
|
||||
cfg: cfg,
|
||||
rc: resty.New().EnableTrace(),
|
||||
locker: &sync.Mutex{},
|
||||
pingMutex: &sync.RWMutex{},
|
||||
isPinging: false,
|
||||
}
|
||||
|
||||
proxyDialer, transport := newProxyDialerAndTransport(cfg)
|
||||
@ -75,7 +80,7 @@ func newManager(cfg Config) *manager {
|
||||
m.rc.SetRetryCount(30)
|
||||
m.rc.SetRetryMaxWaitTime(time.Minute)
|
||||
m.rc.SetRetryAfter(catchRetryAfter)
|
||||
m.rc.AddRetryCondition(shouldRetry)
|
||||
m.rc.AddRetryCondition(m.shouldRetry)
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import (
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// DownloadAndVerify downloads a file and its signature from the given locations `file` and `sig`.
|
||||
@ -50,7 +51,7 @@ func (m *manager) DownloadAndVerify(kr *crypto.KeyRing, url, sig string) ([]byte
|
||||
}
|
||||
|
||||
func (m *manager) fetchFile(url string) ([]byte, error) {
|
||||
res, err := m.rc.R().SetDoNotParseResponse(true).Get(url)
|
||||
res, err := m.r(ContextWithoutRetry(context.Background())).SetDoNotParseResponse(true).Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -30,20 +30,47 @@ var (
|
||||
)
|
||||
|
||||
func (m *manager) pingUntilSuccess() {
|
||||
if m.isPingOngoing() {
|
||||
logrus.Debug("Ping already ongoing")
|
||||
return
|
||||
}
|
||||
m.pingingStarted()
|
||||
defer m.pingingStopped()
|
||||
|
||||
attempt := 0
|
||||
for {
|
||||
err := m.testPing(context.Background())
|
||||
ctx := ContextWithoutRetry(context.Background())
|
||||
err := m.testPing(ctx)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
waitTime := getRetryConnectionSleep(attempt)
|
||||
attempt++
|
||||
logrus.WithError(err).WithField("attempt", attempt).WithField("wait", waitTime).Debug("Connection not available")
|
||||
logrus.WithError(err).WithField("attempt", attempt).WithField("wait", waitTime).Debug("Connection (still) not available")
|
||||
time.Sleep(waitTime)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *manager) isPingOngoing() bool {
|
||||
m.pingMutex.RLock()
|
||||
defer m.pingMutex.RUnlock()
|
||||
|
||||
return m.isPinging
|
||||
}
|
||||
|
||||
func (m *manager) pingingStarted() {
|
||||
m.pingMutex.Lock()
|
||||
defer m.pingMutex.Unlock()
|
||||
m.isPinging = true
|
||||
}
|
||||
|
||||
func (m *manager) pingingStopped() {
|
||||
m.pingMutex.Lock()
|
||||
defer m.pingMutex.Unlock()
|
||||
m.isPinging = false
|
||||
}
|
||||
|
||||
func getRetryConnectionSleep(idx int) time.Duration {
|
||||
if idx >= len(retryConnectionSleeps) {
|
||||
idx = len(retryConnectionSleeps) - 1
|
||||
|
||||
@ -118,11 +118,21 @@ func catchRetryAfter(_ *resty.Client, res *resty.Response) (time.Duration, error
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func shouldRetry(res *resty.Response, err error) bool {
|
||||
func (m *manager) shouldRetry(res *resty.Response, err error) bool {
|
||||
if isRetryDisabled(res.Request.Context()) {
|
||||
return false
|
||||
}
|
||||
return isTooManyRequest(res) || isNoResponse(res, err)
|
||||
if isTooManyRequest(res) {
|
||||
return true
|
||||
}
|
||||
if isNoResponse(res, err) {
|
||||
// Even if the context of request allows to retry we should check
|
||||
// whether the server is reachable or not. In some cases the we can
|
||||
// keep retrying but also report that connection is lost.
|
||||
go m.pingUntilSuccess()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isTooManyRequest(res *resty.Response) bool {
|
||||
|
||||
Reference in New Issue
Block a user