예제 #1
0
func main() {
	var normal tec.TempErrCatcher
	var skipper tec.TempErrCatcher
	skipper.IsTemp = func(e error) bool {
		return e == ErrSkip
	}

	fmt.Println("trying normal (uses Temporary interface)")
	tryTec(normal)
	fmt.Println("")
	fmt.Println("trying skipper (uses our IsTemp function)")
	tryTec(skipper)
}
예제 #2
0
// accept continously accepts incoming connections and
// adds them to the listener's Swarm. is is meant to be
// run in a goroutine.
// TODO: add rate limiting
func (l *Listener) accept() {
	var wg sync.WaitGroup
	defer func() {
		wg.Wait() // must happen before teardown
		l.teardown()
	}()

	// catching the error here is odd. doing what net/http does:
	// http://golang.org/src/net/http/server.go?s=51504:51550#L1728
	// Using the lib: https://godoc.org/github.com/jbenet/go-temp-err-catcher
	var catcher tec.TempErrCatcher

	// rate limit concurrency
	limit := make(chan struct{}, AcceptConcurrency)

	// loop forever accepting connections
	for {
		conn, err := l.netList.Accept()
		if err != nil {
			if catcher.IsTemporary(err) {
				continue
			}
			l.acceptErr <- fmt.Errorf("peerstream listener failed: %s", err)
			return // ok, problems. bail.
		}

		// add conn to swarm and listen for incoming streams
		// do this in a goroutine to avoid blocking the Accept loop.
		// note that this does not rate limit accepts.
		limit <- struct{}{} // sema down
		wg.Add(1)
		go func(conn net.Conn) {
			defer func() { <-limit }() // sema up
			defer wg.Done()

			conn2, err := l.swarm.addConn(conn, true)
			if err != nil {
				l.acceptErr <- err
				return
			}
			conn2.groups.AddSet(&l.groups) // add out groups
		}(conn)
	}
}
예제 #3
0
func tryTec(c tec.TempErrCatcher) {
	errs := []error{
		ErrTemp,
		ErrSkip,
		ErrOther,
		ErrTemp,
		ErrSkip,
		ErrOther,
	}

	for _, e := range errs {
		if c.IsTemporary(e) {
			fmt.Printf("\tIsTemporary: true  - skipped     %s\n", e)
			continue
		}

		fmt.Printf("\tIsTemporary: false - not skipped %s\n", e)
	}
}