stopping a goroutine from outside the go routine

Issue

I have a go routine here that needs to be stopped from the outer go routine when the context expires. However, the go routine doesn’t stop when the context expires and keeps on going even though the go routine controlling it stops.

package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctxParent := context.Background()

    ch := make(chan bool)

    d := 5 * time.Second

    ctx, cancel := context.WithTimeout(ctxParent, d)
    defer cancel()
    go doSomething(ctx, ch)

    // go func() {
    select {

    // done
    case _ = <-ch:
        fmt.Println("goroutine finished")
    }

    fmt.Println("waiting 11 seconds on main thread, ending all go routines")

    time.Sleep(11 * time.Second)

    fmt.Println(">>>> END")
}

func doSomething(ctx context.Context, ch chan<- bool) {

    // how to kill this go routine if context expires??
    go func(ctx context.Context) {
        fmt.Println("LOTS OF WORK TIME..")
        for i := 0; i < 1000; i++ {
            time.Sleep(1 * time.Second) // LOTS OF WORK
            fmt.Println(i)
        }

    }(ctx)

    select {
    case _ = <-ctx.Done():
        fmt.Println("*** Go routine timed out in 5 seconds!!! ****")
        ch <- true
        return

    }
}

this will print (https://play.golang.org/p/L8u51odiHxS)

LOTS OF WORK TIME..
0
1
2
3
4
*** Go routine timed out in 5 seconds!!! ****
goroutine finished
waiting 11 seconds on main thread, ending all go routines
5
6
7
8
9
10
11
12
13
14
15
>>>> END

it should not be printing 5,6,7,8… etc.. Is there a way to kill this inner go routine?

Solution

You have to check for context expiration/cancellation in the goroutine:

 go func(ctx context.Context) {
        fmt.Println("LOTS OF WORK TIME..")
        for i := 0; i < 1000; i++ {
            select {
              case <-ctx.Done():
                  return
              default:
            }
            time.Sleep(1 * time.Second) // LOTS OF WORK
            fmt.Println(i)
        }

    }(ctx)

Answered By – Burak Serdar

Answer Checked By – Willingham (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.