Home > Blockchain >  Clarification required on use of context package in golang
Clarification required on use of context package in golang

Time:02-11

I am learning the Go language. I understand that cancelling a context enables aborting of operations once the parent or related operation is cancelled. This is supposed to save resources of ongoing operations whose results will not be used. Now consider the simple code below:

 package main
 
 import (
    "context"
    "fmt"
    "time"
 )
 
 func main() {
    var result int
    ctx := context.Background()
    ctx, cancel := context.WithCancel(ctx)
    ch1 := make(chan int)
 
    go func() {
        time.Sleep(time.Second * 5)
        //...do some processing
        //Send result on the channel or cancel if error
        //Lets send result...
        ch1 <- 11
    }()
 
    go func() {
        time.Sleep(time.Second * 2)
        //...do some processing
        //Send result on the channel or cancel if error
        //Lets cancel...
        cancel()
    }()
 
    select {
    case result = <-ch1:
        fmt.Println("Processing completed", result)
    case <-ctx.Done():
        fmt.Println("ctx Cancelled")
    }
 
    //Some other processing...  
 
 }

The select statement is satisfied by the ctx.Done(). The question that I have is that even after the cancel is invoked, the first goroutine will continue as the program proceeds with "Some other processing..." Therefore, the basic purpose of using context is not served. I think that I am missing something in my understanding or is there a way to abort the goroutine whose result will not be of any use after the context is cancelled. Please clarify.

CodePudding user response:

The point is you should notify the first goroutine that sth happened, and it need to exit the current routine. That is what select doing as an io-multiplexing provided by golang. The first goroutine should look like this

 go func() {
        select {
        case <-time.After(time.Second * 5):
            //...do some processing
            //Send result on the channel or cancel if error
            //Lets send result...
            ch1 <- 11
        case <-ctx.Done():
            fmt.Println("ctx Cancelled again.")
            return
        }
    }()
  •  Tags:  
  • go
  • Related