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

Data race when running DoTimeout(...) #1140

Closed
Lallassu opened this issue Oct 28, 2021 · 1 comment
Closed

Data race when running DoTimeout(...) #1140

Lallassu opened this issue Oct 28, 2021 · 1 comment

Comments

@Lallassu
Copy link

Lallassu commented Oct 28, 2021

I get a data race from time to time and the below code triggers it. Am I missing something in my DoRequest function to make this race-safe?

The data race (go run -race .): race.log

Code used to trigger it (localhost:80 is just an nginx responding 200 OK with a small body):

package main

import (
	"crypto/tls"
	"fmt"
	"time"

	"github.com/valyala/fasthttp"
	"github.com/valyala/fasthttp/fasthttpproxy"
)

func main() {
        to := time.Second * 2
	go func() {
		for {
			DoRequest(false, "GET", "http://localhost", to)
		}
	}()
	go func() {
		for {
			DoRequest(false, "GET", "http://localhost", to)
		}
	}()
	time.Sleep(60 * time.Second)
}

func DoRequest(verifyTLS bool, method, url string, timeout time.Duration) ([]byte, int, int64, error) {
	req := fasthttp.AcquireRequest()
	resp := fasthttp.AcquireResponse()
	defer fasthttp.ReleaseRequest(req)
	defer fasthttp.ReleaseResponse(resp)

	req.Header.Set("Connection", "close")
	req.Header.SetMethod(method)
	req.SetRequestURI(url)

	client := &fasthttp.Client{
		DialDualStack: true,
		ReadTimeout:   timeout,
		TLSConfig:     &tls.Config{InsecureSkipVerify: !verifyTLS},
		Dial:          fasthttpproxy.FasthttpProxyHTTPDialer(),
	}

	tReqStart := time.Now()

	var body []byte
	err := client.DoTimeout(req, resp, timeout)
	// ReleaseRequest(resp) will re-use underlying data structure so we need a copy here.
	body = append(body, resp.Body()...)

	if err != nil {
		fmt.Printf("failed: %s\n", err.Error())
		return body, resp.StatusCode(), time.Since(tReqStart).Microseconds(), err
	}

	return body, resp.StatusCode(), time.Since(tReqStart).Microseconds(), nil
}

Edit: Using fasthttp 1.31 and Go 1.16.3.

@erikdubbelboer
Copy link
Collaborator

You're right. It seems this pull request, #1106, introduced a race condition. I have fixed it here: 6d4db9b
We'll probably do a new release next week when #1135 is fixed and merged.

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

No branches or pull requests

2 participants