mirror of
https://github.com/restic/restic.git
synced 2024-12-25 17:27:25 +00:00
Merge pull request #3900 from MichaelEischer/b2-init-timeout
Add timeout for the initial connection to B2
This commit is contained in:
commit
8b9778d537
1 changed files with 31 additions and 3 deletions
|
@ -6,6 +6,8 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/restic/restic/internal/backend"
|
"github.com/restic/restic/internal/backend"
|
||||||
"github.com/restic/restic/internal/backend/sema"
|
"github.com/restic/restic/internal/backend/sema"
|
||||||
|
@ -33,11 +35,37 @@ const defaultListMaxItems = 10 * 1000
|
||||||
// ensure statically that *b2Backend implements restic.Backend.
|
// ensure statically that *b2Backend implements restic.Backend.
|
||||||
var _ restic.Backend = &b2Backend{}
|
var _ restic.Backend = &b2Backend{}
|
||||||
|
|
||||||
func newClient(ctx context.Context, cfg Config, rt http.RoundTripper) (*b2.Client, error) {
|
type sniffingRoundTripper struct {
|
||||||
opts := []b2.ClientOption{b2.Transport(rt)}
|
sync.Mutex
|
||||||
|
lastErr error
|
||||||
|
http.RoundTripper
|
||||||
|
}
|
||||||
|
|
||||||
c, err := b2.NewClient(ctx, cfg.AccountID, cfg.Key.Unwrap(), opts...)
|
func (s *sniffingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
res, err := s.RoundTripper.RoundTrip(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
s.Lock()
|
||||||
|
s.lastErr = err
|
||||||
|
s.Unlock()
|
||||||
|
}
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func newClient(ctx context.Context, cfg Config, rt http.RoundTripper) (*b2.Client, error) {
|
||||||
|
sniffer := &sniffingRoundTripper{RoundTripper: rt}
|
||||||
|
opts := []b2.ClientOption{b2.Transport(sniffer)}
|
||||||
|
|
||||||
|
// if the connection B2 fails, this can cause the client to hang
|
||||||
|
// cancel the connection after a minute to at least provide some feedback to the user
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
c, err := b2.NewClient(ctx, cfg.AccountID, cfg.Key.Unwrap(), opts...)
|
||||||
|
if err == context.DeadlineExceeded {
|
||||||
|
if sniffer.lastErr != nil {
|
||||||
|
return nil, sniffer.lastErr
|
||||||
|
}
|
||||||
|
return nil, errors.New("connection to B2 failed")
|
||||||
|
} else if err != nil {
|
||||||
return nil, errors.Wrap(err, "b2.NewClient")
|
return nil, errors.Wrap(err, "b2.NewClient")
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
|
|
Loading…
Reference in a new issue