1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-29 01:12:24 +08:00

updated peerstream: fixed hanging bug

peerstream would hang when it got many temporary errors.
temp errors should not count as an error. Now, it will
only exit when an error is not temporary.

I kept the acceptErr channel because it will no longer
cause a bad hang. The goroutine is exiting, so if it
blocks until acceptErr is read, it's fine. If users
launch tons of listers and see goroutines building up,
they know they should be reading + logging those.
This commit is contained in:
Juan Batiz-Benet
2015-01-11 12:35:15 -08:00
parent b7a4e92121
commit 14b4c8223b
2 changed files with 8 additions and 23 deletions

2
Godeps/Godeps.json generated
View File

@ -144,7 +144,7 @@
},
{
"ImportPath": "github.com/jbenet/go-peerstream",
"Rev": "55792f89d00cf62166668ded3288536cbe6a72cc"
"Rev": "cddf450fca891e45aa471d882dae2c28ac642fb4"
},
{
"ImportPath": "github.com/jbenet/go-random",

View File

@ -2,8 +2,10 @@ package peerstream
import (
"errors"
"fmt"
"net"
"time"
tec "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher"
)
type Listener struct {
@ -62,36 +64,19 @@ func (l *Listener) accept() {
// catching the error here is odd. doing what net/http does:
// http://golang.org/src/net/http/server.go?s=51504:51550#L1728
var tempDelay time.Duration // how long to sleep on accept failure
isTemporaryErr := func(e error) bool {
if ne, ok := e.(net.Error); ok && ne.Temporary() {
if tempDelay == 0 {
tempDelay = 5 * time.Millisecond
} else {
tempDelay *= 2
}
if max := 1 * time.Second; tempDelay > max {
tempDelay = max
}
time.Sleep(tempDelay)
return true
}
return false
}
// Using the lib: https://godoc.org/github.com/jbenet/go-temp-err-catcher
var catcher tec.TempErrCatcher
// loop forever accepting connections
for {
conn, err := l.netList.Accept()
if err != nil {
l.acceptErr <- err
if isTemporaryErr(err) {
if catcher.IsTemporary(err) {
continue
}
l.acceptErr <- fmt.Errorf("peerstream listener failed: %s", err)
return // ok, problems. bail.
}
tempDelay = 0
// add conn to swarm and listen for incoming streams
// log.Printf("accepted conn %s\n", conn.RemoteAddr())