Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to use connection pool by SetTransport. #993

Open
winterant opened this issue Mar 24, 2025 · 0 comments
Open

Failed to use connection pool by SetTransport. #993

winterant opened this issue Mar 24, 2025 · 0 comments

Comments

@winterant
Copy link

winterant commented Mar 24, 2025

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant