-
Notifications
You must be signed in to change notification settings - Fork 10
/
dialer.go
82 lines (72 loc) · 1.56 KB
/
dialer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package dialer
import (
"context"
"errors"
"time"
"github.com/aperturerobotics/bifrost/peer"
bo "github.com/cenkalti/backoff"
"github.com/sirupsen/logrus"
)
// Dialer manages a transport dialer.
type Dialer struct {
// le is the logger
le *logrus.Entry
// tptDialer is the transport dialer.
tptDialer TransportDialer
// backoff is the dialer backoff
backoff bo.BackOff
// peerID is the peer id
peerID peer.ID
// address is the dial address
address string
}
// NewDialer constructs a new Dialer
func NewDialer(
le *logrus.Entry,
tptDialer TransportDialer,
opts *DialerOpts,
peerID peer.ID,
address string,
) *Dialer {
return &Dialer{
le: le.WithField("dial-peer-id", peerID.String()).
WithField("dial-peer-addr", address),
tptDialer: tptDialer,
backoff: opts.GetBackoff().Construct(),
peerID: peerID,
address: address,
}
}
// Execute executes the dialer, with backoff.
func (d *Dialer) Execute(ctx context.Context) error {
for {
d.le.Debug("attempting to dial peer")
fatal, err := d.tptDialer.DialPeer(ctx, d.peerID, d.address)
if err == nil {
d.backoff.Reset()
return nil
}
bo := d.backoff.NextBackOff()
if err != nil {
if err == context.Canceled {
return err
}
if fatal {
d.le.WithError(err).Warn("dialer errored fatally")
return err
}
d.le.
WithError(err).
WithField("backoff", bo.String()).
Warn("dialer errored")
}
if bo == -1 {
return errors.New("dial backoff max duration exceeded")
}
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(bo):
}
}
}