Refactor HTTP transport to be a singleton and update connection settingsUnverified
8ea190a parent: 9f09d5b modified
internal/httpclient/httpclient.go +28 -15 | @@ -6,6 +6,7 @@ import ( | ||
| 6 | 6 | "net" |
| 7 | 7 | "net/http" |
| 8 | 8 | "strconv" |
| 9 | + "sync" | |
| 9 | 10 | "time" |
| 10 | 11 | ) |
| 11 | 12 | |
| @@ -24,26 +25,38 @@ var dnsResolver = &net.Resolver{ | ||
| 24 | 25 | }, |
| 25 | 26 | } |
| 26 | 27 | |
| 27 | -func NewTransport() *http.Transport { | |
| 28 | - dialer := &net.Dialer{ | |
| 29 | - Timeout: 5 * time.Second, | |
| 30 | - KeepAlive: 15 * time.Second, | |
| 31 | - FallbackDelay: 300 * time.Millisecond, | |
| 32 | - Resolver: dnsResolver, | |
| 33 | - } | |
| 28 | +var ( | |
| 29 | + transportOnce sync.Once | |
| 30 | + sharedTransport *http.Transport | |
| 31 | +) | |
| 34 | 32 | |
| 35 | - return &http.Transport{ | |
| 36 | - DialContext: dialer.DialContext, | |
| 37 | - MaxIdleConns: 50, | |
| 38 | - IdleConnTimeout: 10 * time.Second, | |
| 39 | - TLSHandshakeTimeout: 5 * time.Second, | |
| 40 | - ForceAttemptHTTP2: true, | |
| 41 | - } | |
| 33 | +func DefaultTransport() *http.Transport { | |
| 34 | + transportOnce.Do(func() { | |
| 35 | + dialer := &net.Dialer{ | |
| 36 | + Timeout: 5 * time.Second, | |
| 37 | + KeepAlive: 15 * time.Second, | |
| 38 | + FallbackDelay: 300 * time.Millisecond, | |
| 39 | + Resolver: dnsResolver, | |
| 40 | + } | |
| 41 | + | |
| 42 | + sharedTransport = &http.Transport{ | |
| 43 | + DialContext: dialer.DialContext, | |
| 44 | + MaxIdleConns: 100, | |
| 45 | + MaxIdleConnsPerHost: 10, | |
| 46 | + IdleConnTimeout: 90 * time.Second, | |
| 47 | + TLSHandshakeTimeout: 5 * time.Second, | |
| 48 | + ForceAttemptHTTP2: true, | |
| 49 | + } | |
| 50 | + }) | |
| 51 | + return sharedTransport | |
| 52 | +} | |
| 53 | + | |
| 54 | +func NewTransport() *http.Transport { | |
| 55 | + return DefaultTransport() | |
| 42 | 56 | } |
| 43 | 57 | |
| 44 | 58 | func SetDefaultHeaders(req *http.Request) { |
| 45 | 59 | req.Header.Set("User-Agent", UserAgent) |
| 46 | - req.Header.Set("Connection", "close") | |
| 47 | 60 | } |
| 48 | 61 | |
| 49 | 62 | func ParseRetryAfter(v string) time.Duration { |
| @@ -6,6 +6,7 @@ import ( | |||
| 6 | "net" | 6 | "net" |
| 7 | "net/http" | 7 | "net/http" |
| 8 | "strconv" | 8 | "strconv" |
| 9 | + "sync" | ||
| 9 | "time" | 10 | "time" |
| 10 | ) | 11 | ) |
| 11 | 12 | ||
| @@ -24,26 +25,38 @@ var dnsResolver = &net.Resolver{ | |||
| 24 | }, | 25 | }, |
| 25 | } | 26 | } |
| 26 | 27 | ||
| 27 | -func NewTransport() *http.Transport { | 28 | +var ( |
| 28 | - dialer := &net.Dialer{ | 29 | + transportOnce sync.Once |
| 29 | - Timeout: 5 * time.Second, | 30 | + sharedTransport *http.Transport |
| 30 | - KeepAlive: 15 * time.Second, | 31 | +) |
| 31 | - FallbackDelay: 300 * time.Millisecond, | ||
| 32 | - Resolver: dnsResolver, | ||
| 33 | - } | ||
| 34 | 32 | ||
| 35 | - return &http.Transport{ | 33 | +func DefaultTransport() *http.Transport { |
| 36 | - DialContext: dialer.DialContext, | 34 | + transportOnce.Do(func() { |
| 37 | - MaxIdleConns: 50, | 35 | + dialer := &net.Dialer{ |
| 38 | - IdleConnTimeout: 10 * time.Second, | 36 | + Timeout: 5 * time.Second, |
| 39 | - TLSHandshakeTimeout: 5 * time.Second, | 37 | + KeepAlive: 15 * time.Second, |
| 40 | - ForceAttemptHTTP2: true, | 38 | + FallbackDelay: 300 * time.Millisecond, |
| 41 | - } | 39 | + Resolver: dnsResolver, |
| 40 | + } | ||
| 41 | + | ||
| 42 | + sharedTransport = &http.Transport{ | ||
| 43 | + DialContext: dialer.DialContext, | ||
| 44 | + MaxIdleConns: 100, | ||
| 45 | + MaxIdleConnsPerHost: 10, | ||
| 46 | + IdleConnTimeout: 90 * time.Second, | ||
| 47 | + TLSHandshakeTimeout: 5 * time.Second, | ||
| 48 | + ForceAttemptHTTP2: true, | ||
| 49 | + } | ||
| 50 | + }) | ||
| 51 | + return sharedTransport | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +func NewTransport() *http.Transport { | ||
| 55 | + return DefaultTransport() | ||
| 42 | } | 56 | } |
| 43 | 57 | ||
| 44 | func SetDefaultHeaders(req *http.Request) { | 58 | func SetDefaultHeaders(req *http.Request) { |
| 45 | req.Header.Set("User-Agent", UserAgent) | 59 | req.Header.Set("User-Agent", UserAgent) |
| 46 | - req.Header.Set("Connection", "close") | ||
| 47 | } | 60 | } |
| 48 | 61 | ||
| 49 | func ParseRetryAfter(v string) time.Duration { | 62 | func ParseRetryAfter(v string) time.Duration { |