Code-Memo

Channels, select, and context

Go does not use async/await. Cooperative multitasking uses goroutines, channels, select, and context for cancellation and deadlines.

Channels
ch := make(chan int)      // unbuffered: synchronous rendezvous
buf := make(chan int, 10) // buffered: sends block when full

Send and receive block until the other side is ready (for unbuffered) or buffer has space/data.

close and range
close(ch)
for v := range ch {
	_ = v
}

Only the sender should close, unless using a clear ownership pattern.

select

Multiplexes on channel operations; one random ready case runs if multiple are ready.

select {
case v := <-ch:
	_ = v
case <-time.After(5 * time.Second):
	// timeout
case <-ctx.Done():
	return ctx.Err()
}
context
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

req, _ := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)

Pass context.Context as the first argument of functions that do I/O or long work.

Common mistakes
Buffered channel as semaphore
sem := make(chan struct{}, 3)
for _, job := range jobs {
	sem <- struct{}{}
	go func(job Job) {
		defer func() { <-sem }()
		run(job)
	}(job)
}