Concurrency

Concurrency #

How to count active goroutines #

ctx, cancel := context.WithCancel(context.Background())

watcherWg := &sync.WaitGroup{}
watcherWg.Add(1)
go func() {
    defer func() {
        watcherWg.Done()
        fmt.Printf("\nFinishing...\nLeft %d goroutines", runtime.NumGoroutine())
    }()
    
    t := time.NewTicker(time.Millisecond * 500)
    defer t.Stop()
    for {
        select {
        case <-t.C:
            fmt.Printf("Currently running %d goroutines\n", runtime.NumGoroutine())
        case <-ctx.Done():
            return
        }
    }
}()

time.Sleep(time.Second)
wg := &sync.WaitGroup{}
for i := 0; i < 2; i++ {
    wg.Add(1)
    go func(d int, w *sync.WaitGroup) {
        defer wg.Done()
        dur := time.Duration(rand.Intn(5)) * time.Second
        fmt.Printf("Gopher %d started the job[%d sec]\n", d, dur/time.Second)
        time.Sleep(dur)
        fmt.Printf("Gopher %d finished the job\n", d)
    }(i, wg)
}

wg.Wait()
cancel()
watcherWg.Wait()

Retry to send to blocked channel #

package main

import (
	"fmt"
	"time"
)

func main() {
	tick := time.Tick(time.Second)
	ch := make(chan int)

	go func() {
		time.Sleep(time.Second*2)
		fmt.Println(<-ch)
	}()

	retry := 3

	for retry > 0 {
		select {
		case ch <- 1:
			fmt.Println("sent 1")
			retry = 0
		case <-tick:
			fmt.Printf("timeout, %d more retries\n", retry)
			retry--
		}
	}
}

© 2020 Amanbolat Balabekov