Search code examples
gogoroutine

Why go routine works till end from a Gin's handler


I know that if the goroutine B is started from a certain goroutine A, and if the goroutine A ends, no matter how far does goroutine B steps, it will be ended up forcefully.

func main()  {
    go simulateGinAPI()
    fmt.Println("finish...")
}

func simulateGinAPI() {
    fmt.Println("ginAPI....")
    go backgroundProcess()
}


func backgroundProcess() {
    fmt.Println("calculating...")
    fmt.Println(calculate(45))
}

func calculate(x int) int {
    if x < 2 {
        return x
    }
    return calculate(x-1) + calculate(x-2)
}

output

finish...

As the output log shows. Result of Fibonacci sum will not be logged out, instead, only "finish" was logged out.


However, as the code below shows, if we start gorouting from a Gin's handle, even the response was sent, goroutine for calculating the result of Fibonacci sum will still be run to the end.


func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        go backgroundProcess()
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

func simulateGinAPI() {
    fmt.Println("ginAPI....")
    go backgroundProcess()
}


func backgroundProcess() {
    fmt.Println("calculating...")
    fmt.Println(calculate(45))
}

func calculate(x int) int {
    if x < 2 {
        return x
    }
    return calculate(x-1) + calculate(x-2)
}

enter image description here

output

[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
calculating...
[GIN] 2021/12/20 - 11:31:46 | 200 |      56.425µs |             ::1 | GET      "/ping"
1134903170 <- result of Fibonacci's sum.

Question:

  1. Why the goroutine started from handle of gin was not end up forcefully after the gin's handle send response?
  2. Should not the goroutine of the handle be ended up after the response was sent?
  3. Should not the goroutine started from handle be ended up forcefully with the end of the goroutine on the handle?

Solution

  • I know that if the goroutine B is started from a certain goroutine A, and if the goroutine A ends, no matter how far does goroutine B steps, it will be ended up forcefully.

    It's not correct. If the main function exits, all the goroutines will be exited too.

    But if the main function continues running, although the goroutine caller function exits, that goroutine will continue its course.

    This happened in your example too.

    Your example code exits before it could calculate the Fibonacci sum. But your server code continues running. That's why this behavior from the code.

    If you altered your example code a bit, you could see that your program also calculates the Fibonacci sum.

    Here's the example: https://goplay.tools/snippet/dMCyUqweyu8