HTTPTransport: implement queue for listener.

Before this patch, when an error occurs in trying to accept a connection
from the listener, the error would be returned. This also happened on
temporary issues like `too many open files`.

Temporary issues are "self-healing" and will resolve over time. This
means that we can put the requests in a queue to wait until the issue is
resolved and start processing the connections once it is resolved.

This patch implements such mechanism, as copied from the standard
library http package. It will retry temporary errors but will return
permanent errors (or errors that are not from the net.Error type).
This commit is contained in:
Jelmer Snoeck 2016-04-01 13:10:18 +01:00
parent ce283ab233
commit af0028d821

View File

@ -8,12 +8,14 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"log"
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time"
mls "github.com/micro/misc/lib/tls" mls "github.com/micro/misc/lib/tls"
) )
@ -309,9 +311,23 @@ func (h *httpTransportListener) Close() error {
} }
func (h *httpTransportListener) Accept(fn func(Socket)) error { func (h *httpTransportListener) Accept(fn func(Socket)) error {
var tempDelay time.Duration
for { for {
c, err := h.listener.Accept() c, err := h.listener.Accept()
if err != nil { if err != nil {
if ne, ok := err.(net.Error); ok && ne.Temporary() {
if tempDelay == 0 {
tempDelay = 5 * time.Millisecond
} else {
tempDelay *= 2
}
if max := 1 * time.Second; tempDelay > max {
tempDelay = max
}
log.Printf("http: Accept error: %v; retrying in %v\n", err, tempDelay)
time.Sleep(tempDelay)
continue
}
return err return err
} }