This is my 2nd day of learning go lang and I'm trying to figure out how to make non-blocking http request.
I'm using gin framework and I have very simple code as below.
func main() {
r := gin.Default()
r.GET("test", func(c *gin.Context){
request := gorequest.New()
_, body, _ := request.Get("http://tmp.com").End()
c.JSON(200, body)
})
r.Run()
}
tmp.com is a local server, which takes 0.5 second to response (I created it for testing)
When I do a simple ab test on the go server with wrk -t2 -c50 http://127.0.0.1:8080/test
, I get about 8 requests/sec.
It looks like the request is getting blocked.
I've tried to separate the request into a function then call it with "go" to use coroutine, but that simply returned nothing.
My revised code is
func makeRequest(c *gin.Context) {
request := gorequest.New()
_, body, _ := request.Get("http://tmp.com").End()
c.JSON(200, body)
}
func main() {
r := gin.Default()
r.GET("test", func(c *gin.Context){
go makeRequest(c)
})
r.Run()
}
Is there a simple way to make non-blocking request? or what's the best approach in this case?
that cannot work, as commented, the http protocol is synchronous.
In the op code the response is sent and written, by the underlying framework, before the parallel makeRequest
function call finished its job.
If the response is ever written to the client, the client must actively refuse it, as this is not a normal behavior for this protocol.
What is unfortunate in OP code is that the gin
package won t trigger an error if it tries to write on a closed response.
As answered already, each HTTP request is handled in it's own go routine. HTTP is a natural fit for the request/response pattern. If you really needed to communicate asynchronously over HTTP you could use a callback function. However I would suggest using event based messaging.