h2non / gentleman

Plugin-driven, extensible HTTP client toolkit for Go

Home Page:https://pkg.go.dev/github.com/h2non/gentleman?tab=doc

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Finalizers are used incorrectly?

eyalpost opened this issue · comments

Some of our tests are run with --race to check for race conditions and I have traced an issue with a failing test that seem to come from gentelmen's use of finalizer.
There are a few uses of runtime.SetFinalizer() which I believe are incorrect.
See the following code:

func SetTransportFinalizer(transport *http.Transport) {
	runtime.SetFinalizer(&transport, func(t **http.Transport) {
		(*t).CloseIdleConnections()
	})
}

You get a pointer to an http.Transport and you're setting a finalizer for the pointer to that pointer. This means that the finalizer will fire when the local variable is GCed and not when the value itself.
Suggestions

  • The following solves the issue for us:
func SetTransportFinalizer(transport *http.Transport) {
	runtime.SetFinalizer(transport, func(t *http.Transport) {
		t.CloseIdleConnections()
	})
}
  • this probably needs to be changed also in response.EnsureResponseFinalized too

  • But.. I think you should reconsider the usage of the finalizer at all. I know it as been copied from Hashicorp's go-cleanhttp package but note that they have removed that from their package.

  • Also note that in the same file you have an almost identical func EnsureTransporterFinalized() which doesn't seem to be used anywhere.

commented

In recent versions of Go this would not be required. I will fix sometime soon, or alternatively you could send a PR if you want.

Will send a PR tomorrow. How do you want to fix? Remove finalizer entirely?

commented

Yeah, I think removing it would be more convenient at this point.