Open
Description
Usually, we'd like using connection pool to optimize system performance. For resty v3, SetTransport
allows us to set max connection. However, it doesn't work. For example:
package main
import (
"fmt"
"log"
"net/http"
"resty.dev/v3"
"time"
)
func main() {
client := resty.New().SetTransport(&http.Transport{
MaxIdleConnsPerHost: 1,
MaxConnsPerHost: 1,
IdleConnTimeout: 60 * time.Second,
})
// client.SetDebug(true)
for i := 0; i < 2; i++ {
fmt.Printf("\n====== test %d ======\n", i+1)
resp, err := client.R().
SetHeader("Connection", "keep-alive").
EnableTrace().
Get("http://httpbin.org/get")
ti := resp.Request.TraceInfo()
fmt.Println("Request Trace Info:")
fmt.Println(" DNSLookup :", ti.DNSLookup)
fmt.Println(" ConnTime :", ti.ConnTime)
fmt.Println(" TCPConnTime :", ti.TCPConnTime)
fmt.Println(" TLSHandshake :", ti.TLSHandshake)
fmt.Println(" ServerTime :", ti.ServerTime)
fmt.Println(" ResponseTime :", ti.ResponseTime)
fmt.Println(" TotalTime :", ti.TotalTime)
fmt.Println(" IsConnReused :", ti.IsConnReused)
fmt.Println(" IsConnWasIdle :", ti.IsConnWasIdle)
fmt.Println(" ConnIdleTime :", ti.ConnIdleTime)
if err != nil {
log.Printf("error: %v\n", err)
} else {
fmt.Printf("response status: %s\n", resp.Status())
}
}
}
Stdout:
====== test 1 ======
Request Trace Info:
DNSLookup : 7.926584ms
ConnTime : 383.178667ms
TCPConnTime : 374.85325ms
TLSHandshake : 0s
ServerTime : 264.704667ms
ResponseTime : 108.208µs
TotalTime : 647.653292ms
IsConnReused : false
IsConnWasIdle : false
ConnIdleTime : 0s
response status: 200 OK
====== test 2 ======
<------ Hang at here. I can only force the process to be killed
Expectedly, the second time, TCPConn should be reused. But it doesn't, it will hang before the second time to call client.R().Get()
.
What's interesting is that if enable client.SetDebug(true)
at the line 17 everything will meet expectations:
====== test 1 ======
2025/03/24 19:23:27.758266 DEBUG RESTY
==============================================================================
~~~ REQUEST ~~~
GET /get HTTP/1.1
HOST : httpbin.org
HEADERS:
Accept-Encoding: gzip, deflate
Connection: keep-alive
User-Agent: go-resty/3.0.0-beta.1 (https://resty.dev)
BODY :
***** NO CONTENT *****
------------------------------------------------------------------------------
~~~ RESPONSE ~~~
STATUS : 200 OK
PROTO : HTTP/1.1
RECEIVED AT : 2025-03-24T19:23:27.757659+08:00
DURATION : 725.12975ms
HEADERS :
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 305
Content-Type: application/json
Date: Mon, 24 Mar 2025 11:23:27 GMT
Server: gunicorn/19.9.0
BODY :
{
"args": {},
"headers": {
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "go-resty/3.0.0-beta.1 (https://resty.dev)",
"X-Amzn-Trace-Id": "Root=1-67e140af-4344002e59387a2e6dad486a"
},
"origin": "111.108.111.135",
"url": "http://httpbin.org/get"
}
------------------------------------------------------------------------------
TRACE INFO:
DNSLookupTime : 48.719917ms
ConnTime : 427.163833ms
TCPConnTime : 378.175875ms
TLSHandshake : 0s
ServerTime : 298.028709ms
ResponseTime : 154.958µs
TotalTime : 725.12975ms
IsConnReused : false
IsConnWasIdle : false
ConnIdleTime : 0s
RequestAttempt: 1
RemoteAddr : 100.28.166.39:80
==============================================================================
Request Trace Info:
DNSLookup : 48.719917ms
ConnTime : 427.163833ms
TCPConnTime : 378.175875ms
TLSHandshake : 0s
ServerTime : 298.028709ms
ResponseTime : 154.958µs
TotalTime : 725.12975ms
IsConnReused : false
IsConnWasIdle : false
ConnIdleTime : 0s
response status: 200 OK
====== test 2 ======
2025/03/24 19:23:28.051593 DEBUG RESTY
==============================================================================
~~~ REQUEST ~~~
GET /get HTTP/1.1
HOST : httpbin.org
HEADERS:
Accept-Encoding: gzip, deflate
Connection: keep-alive
User-Agent: go-resty/3.0.0-beta.1 (https://resty.dev)
BODY :
***** NO CONTENT *****
------------------------------------------------------------------------------
~~~ RESPONSE ~~~
STATUS : 200 OK
PROTO : HTTP/1.1
RECEIVED AT : 2025-03-24T19:23:28.051324+08:00
DURATION : 292.801583ms
HEADERS :
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 305
Content-Type: application/json
Date: Mon, 24 Mar 2025 11:23:28 GMT
Server: gunicorn/19.9.0
BODY :
{
"args": {},
"headers": {
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "go-resty/3.0.0-beta.1 (https://resty.dev)",
"X-Amzn-Trace-Id": "Root=1-67e140b0-1b19e79171754077680b1b64"
},
"origin": "111.108.111.135",
"url": "http://httpbin.org/get"
}
------------------------------------------------------------------------------
TRACE INFO:
DNSLookupTime : 0s
ConnTime : 10.667µs
TCPConnTime : 0s
TLSHandshake : 0s
ServerTime : 292.700791ms
ResponseTime : 90.125µs
TotalTime : 292.801583ms
IsConnReused : true
IsConnWasIdle : true
ConnIdleTime : 786.459µs
RequestAttempt: 1
RemoteAddr : 100.28.166.39:80
==============================================================================
Request Trace Info:
DNSLookup : 0s
ConnTime : 10.667µs
TCPConnTime : 0s
TLSHandshake : 0s
ServerTime : 292.700791ms
ResponseTime : 90.125µs
TotalTime : 292.801583ms
IsConnReused : true
IsConnWasIdle : true
ConnIdleTime : 786.459µs
response status: 200 OK
As expected, the second time that IsConnReused
is true.
Anybody explains that? All my need is reuse connection without enable debug.
Metadata
Metadata
Assignees
Labels
No labels