peer: remove write backoff

This commit removes the write backoff, since subsequent retries no
longer need to access the write pool. Subsequent flushes will resume
writing any partial writes that occurred before the timeout until the
message is received or the idle write timer is triggered.

In the future, we can add callbacks that execute on write events
timeouts. This can be useful for mobile clients that might roam, as the
timeout could indicate the connection is dead even if the OS has not
reported it closed. The callback can be used then, for example, to
initiate another outbound connection to test whether or not the issue is
related to the connection.
This commit is contained in:
Conner Fromknecht 2019-04-22 16:05:41 -07:00
parent bfbf3015ad
commit e013577a4f
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7

46
peer.go

@ -1493,11 +1493,6 @@ func (p *peer) writeHandler() {
var exitErr error var exitErr error
const (
minRetryDelay = 5 * time.Second
maxRetryDelay = time.Minute
)
out: out:
for { for {
select { select {
@ -1517,49 +1512,16 @@ out:
// message. // message.
startTime := time.Now() startTime := time.Now()
// Initialize a retry delay of zero, which will be retry:
// increased if we encounter a write timeout on the
// send.
var retryDelay time.Duration
retryWithDelay:
if retryDelay > 0 {
select {
case <-time.After(retryDelay):
case <-p.quit:
// Inform synchronous writes that the
// peer is exiting.
if outMsg.errChan != nil {
outMsg.errChan <- ErrPeerExiting
}
exitErr = ErrPeerExiting
break out
}
}
// Write out the message to the socket. If a timeout // Write out the message to the socket. If a timeout
// error is encountered, we will catch this and retry // error is encountered, we will catch this and retry
// after backing off in case the remote peer is just // after backing off in case the remote peer is just
// slow to process messages from the wire. // slow to process messages from the wire.
err := p.writeMessage(outMsg.msg) err := p.writeMessage(outMsg.msg)
if nerr, ok := err.(net.Error); ok && nerr.Timeout() { if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
// Increase the retry delay in the event of a
// timeout error, this prevents us from
// disconnecting if the remote party is slow to
// pull messages off the wire. We back off
// exponentially up to our max delay to prevent
// blocking the write pool.
if retryDelay == 0 {
retryDelay = minRetryDelay
} else {
retryDelay *= 2
if retryDelay > maxRetryDelay {
retryDelay = maxRetryDelay
}
}
peerLog.Debugf("Write timeout detected for "+ peerLog.Debugf("Write timeout detected for "+
"peer %s, retrying after %v, "+ "peer %s, first write for message "+
"first attempted %v ago", p, retryDelay, "attempted %v ago", p,
time.Since(startTime)) time.Since(startTime))
// If we received a timeout error, this implies // If we received a timeout error, this implies
@ -1571,7 +1533,7 @@ out:
// reserializing or reencrypting it. // reserializing or reencrypting it.
outMsg.msg = nil outMsg.msg = nil
goto retryWithDelay goto retry
} }
// The write succeeded, reset the idle timer to prevent // The write succeeded, reset the idle timer to prevent