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

The results produced by Gorame and Gin when encountering a context canceled in the http server are inconsistent. #2966

Closed
merlin888888 opened this issue Sep 15, 2023 · 6 comments
Labels

Comments

@merlin888888
Copy link

merlin888888 commented Sep 15, 2023

Environment description

  1. go1.20.1 windows/amd64
  2. gf/v2 v2.5.1
  3. gin-gonic/gin v1.9.1

use gf HTTP Server like this,No server timeout has been set。default configuration

	s := g.Server()
	s.BindHandler("/ces/", func(r *ghttp.Request) {
		time.Sleep(3 * time.Second)
		fmt.Println("contextErr:", r.GetCtx().Err())
		r.Response.Write("ces")
	})
	s.Run()
       // Will output:contextErr: context canceled

use Gin HTTP Server like this

	r := gin.New()
	r.POST("/ces", func(c *gin.Context) {
		time.Sleep(3 * time.Second)
		fmt.Println("contextErr,,", c.Err())
		c.JSON(http.StatusOK, gin.H{
			"message": "pong",
		})
	})
	r.Run()

    // Will output:contextErr,, nil

use http Client like this,No server timeout has been set。default configuration

	host := "http://127.0.0.1:30300/ces"
	client := &http.Client{}
	request, err := http.NewRequest("POST", host, strings.NewReader(""))
	if err != nil {
		fmt.Println(err)
		return
	}
	ctx, cancel := context.WithCancel(context.Background())
	request = request.WithContext(ctx)
	go func() {
		time.Sleep(200 * time.Millisecond)
		cancel() // cancel after 200ms
	}()
	response, err := client.Do(request)
	if err != nil {
		fmt.Println("Fatal error ", err.Error())
		return
	}
	defer response.Body.Close()

use Goland DEBUG show this

微信图片_20230915093003

What did you expect to see?

The results of Gorame and Gin are inconsistent. Could you please explain what kind of processing Gorame is performing that could lead to this result? In other Http invocation processes, the cancellation of the context is only cancle by the standard library http/server when it reaches finishRequest.

Gorame运行的结果和Gin运行结果不一致,请问Gorame是进行怎样的处理导致出现此种结果。在其它框架Http调用过程中,context的cancle由标准库http/server在执行到finishRequest才会cancle。请问下当前框架层面是如何监听并处理context cancle的?

@hailaz
Copy link
Member

hailaz commented Sep 15, 2023

要不你试试这样?

r := gin.New()
r.GET("/ces", func(c *gin.Context) {
    time.Sleep(3 * time.Second)
    fmt.Println("contextErr,,", c.Err())
    fmt.Println("Request contextErr,,", c.Request.Context().Err())// here
    c.JSON(http.StatusOK, gin.H{
	    "message": "pong",
    })
})
r.Run()

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


How about you try this?

r := gin.New()
r.GET("/ces", func(c *gin.Context) {
    time.Sleep(3 * time.Second)
    fmt.Println("contextErr,,", c.Err())
    fmt.Println("Request contextErr,,", c.Request.Context().Err())// here
    c.JSON(http.StatusOK, gin.H{
"message": "pong",
    })
})
r.Run()

@merlin888888
Copy link
Author

要不你试试这样?

r := gin.New()
r.GET("/ces", func(c *gin.Context) {
    time.Sleep(3 * time.Second)
    fmt.Println("contextErr,,", c.Err())
    fmt.Println("Request contextErr,,", c.Request.Context().Err())// here
    c.JSON(http.StatusOK, gin.H{
	    "message": "pong",
    })
})
r.Run()

你好,用下面这个断点调试可以了,请问下为何在断点调试过程中需要调用 c.Request.Context().Err(),才会触发contex cancled 。如果不调用,contex的err状态会在执行到finishRequest才触发,可有相关资料或源码指点一下

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


How about you try this?

r := gin.New()
r.GET("/ces", func(c *gin.Context) {
time.Sleep(3 * time.Second)
fmt.Println("contextErr,,", c.Err())
fmt.Println("Request contextErr,,", c.Request.Context().Err())// here
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
r.Run()

Hello, you can debug using the following breakpoint. May I ask why you need to call c.Request.Context().Err() during breakpoint debugging to trigger context canceled? If it is not called, the err status of contex will not be triggered until finishRequest is executed. Can you provide relevant information or source code?

@gqcn
Copy link
Member

gqcn commented Sep 18, 2023

@merlin888888 你好,你的Client设置了超时取消,那么服务端报错context cancel是正常的行为哈。

@gqcn gqcn closed this as completed Sep 18, 2023
@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@merlin888888 Hello, your Client is set to timeout cancellation, so it is normal behavior for the server to report an error context cancel.

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

No branches or pull requests

4 participants