Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Sequence of events leading up to cancellation of context

In the below program, there is a select sequence in both C1 & C2. A deadline context for 1.5 seconds is defined in C1, which after the deadline, cancels the context, leads to ctx.Done() and prevents the reading of integers in C2 which would further cancel the context and lead to ctx.Done() in C1.

If that is the case then what use is cancelCtx() in C1 when the context is already being cancelled?

package main

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

func main() {
    ctx := context.Background()
    C1(ctx)
}
func C1(ctx context.Context) {
    deadline := time.Now().Add(1500 * time.Millisecond) 
    ctx, cancelCtx := context.WithDeadline(ctx, deadline)
    printCh := make(chan int) 
    go C2(ctx, printCh)
    for num := 1; num <= 3; num++ {
        select {
        case printCh <- num:
            time.Sleep(1 * time.Second)
        case <-ctx.Done():
            fmt.Printf("C1: Finished\n")
        }
    }
    cancelCtx()
    time.Sleep(100 * time.Millisecond)
}
func C2(ctx context.Context, printCh <-chan int) {
    for {
        select {
        case num := <-printCh:
            fmt.Printf("C2: %d\n", num)
        case <-ctx.Done():
            if err := ctx.Err(); err != nil {
                fmt.Printf("C2 Error: %s\n", err)
            }
            fmt.Printf("C2: Finished\n")
            return
        }
    }
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

As per the docs for context.WithDeadline():

Canceling this context releases resources associated with it, so code should call cancel as soon as the operations running in this Context complete.

So best practice is to call cancelCtx() (or whatever you call the function) as soon as you no longer need it (it’s fairly common to defer cancel() even if this means it’s called multiple times).

In your example there is another reason that this might be beneficial. Lets assume that the deadline is configurable and has been increased to 5 seconds; now cancelling the context leads to the termination of C2 being triggered by the call cancelCtx() instead of waiting until the deadline (playground).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading