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.
Juan Batiz-Benet committed
Jan 11, 2015 at 12:35 UTC
14b4c8223bf21cbc6801ff15bb70576e907074b0
2 files changed
+8
-23
Godeps/Godeps.json
+1
-1
@@ -144,7 +144,7 @@
144
},
145
{
146
"ImportPath": "github.com/jbenet/go-peerstream",
147
- "Rev": "55792f89d00cf62166668ded3288536cbe6a72cc"
147
+ "Rev": "cddf450fca891e45aa471d882dae2c28ac642fb4"
148
},
149
{
150
"ImportPath": "github.com/jbenet/go-random",
Godeps/_workspace/src/github.com/jbenet/go-peerstream/listener.go
+7
-22
@@ -2,8 +2,10 @@ package peerstream
2
3
import (
4
"errors"
5
+ "fmt"
6
"net"
6
- "time"
7
+
8
+ tec "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher"
9
)
10
11
type Listener struct {
@@ -62,36 +64,19 @@ func (l *Listener) accept() {
64
65
// catching the error here is odd. doing what net/http does:
66
// http://golang.org/src/net/http/server.go?s=51504:51550#L1728
65
- var tempDelay time.Duration // how long to sleep on accept failure
66
-
67
- isTemporaryErr := func(e error) bool {
68
- if ne, ok := e.(net.Error); ok && ne.Temporary() {
69
- if tempDelay == 0 {
70
- tempDelay = 5 * time.Millisecond
71
- } else {
72
- tempDelay *= 2
73
- }
74
- if max := 1 * time.Second; tempDelay > max {
75
- tempDelay = max
76
- }
77
-
78
- time.Sleep(tempDelay)
79
- return true
80
- }
81
- return false
82
- }
67
+ // Using the lib: https://godoc.org/github.com/jbenet/go-temp-err-catcher
68
+ var catcher tec.TempErrCatcher
69
70
// loop forever accepting connections
71
for {
72
conn, err := l.netList.Accept()
73
if err != nil {
88
- l.acceptErr <- err
89
- if isTemporaryErr(err) {
74
+ if catcher.IsTemporary(err) {
75
continue
76
}
77
+ l.acceptErr <- fmt.Errorf("peerstream listener failed: %s", err)
78
return // ok, problems. bail.
79
}
94
- tempDelay = 0
80
81
// add conn to swarm and listen for incoming streams
82
// log.Printf("accepted conn %s\n", conn.RemoteAddr())