golang for and select usage

 In Golang, for and select are used quite commonly with each other. For example, the following code would continue to run at certain interval before it receive context cancellation request and terminates. 

package main

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

func main() {
    // Create a parent context and a cancel function
    ctx, cancel := context.WithCancel(context.Background())

    // Start a goroutine that does some work
    go doWork(ctx)

    // Let it run for 3 seconds, then cancel
    time.Sleep(3 * time.Second)
    fmt.Println("Main: Cancelling the context...")
    cancel() // This signals all goroutines using this context to stop

    // Wait a bit to see the cancellation take effect
    time.Sleep(1 * time.Second)
    fmt.Println("Main: Done")
}

func doWork(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            // Context was cancelled, exit gracefully
            fmt.Println("Worker: Received cancellation signal, stopping...")
            return
        default:
            // Do some work
            fmt.Println("Worker: Working...")
            time.Sleep(500 * time.Millisecond)
        }
    }
}

The output from here is,

Worker: Working...
Worker: Working...
Worker: Working...
Worker: Working...
Worker: Working...
Worker: Working...
Worker: Working...
Main: Cancelling the context...
Worker: Received cancellation signal, stopping...
Main: Done


What will happen if we remove, for {} loop in there? Like so 


package main

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

func main() {
    // Create a parent context and a cancel function
    ctx, cancel := context.WithCancel(context.Background())

    // Start a goroutine that does some work
    go doWork(ctx)

    // Let it run for 3 seconds, then cancel
    time.Sleep(3 * time.Second)
    fmt.Println("Main: Cancelling the context...")
    cancel() // This signals all goroutines using this context to stop

    // Wait a bit to see the cancellation take effect
    time.Sleep(1 * time.Second)
    fmt.Println("Main: Done")
}

func doWork(ctx context.Context) {
    //for {
        select {
        case <-ctx.Done():
            // Context was cancelled, exit gracefully
            fmt.Println("Worker: Received cancellation signal, stopping...")
            return
        default:
            // Do some work
            fmt.Println("Worker: Working...")
            time.Sleep(500 * time.Millisecond)
        }
    //}
}


The goroutine would stop checking for context done and do the defaults. It will be a sequential execution where main thread call goroutine, goroutine outputs the message. Then main thread waits for 3 seconds and then send cancellation. So the output looks something like this. 

Worker: Working...
Main: Cancelling the context...
Main: Done

Comments

Popular posts from this blog

gemini cli getting file not defined error

NodeJS: Error: spawn EINVAL in window for node version 20.20 and 18.20

vllm : Failed to infer device type