Context & select

Базовая Ρ€Π°Π±ΠΎΡ‚Π° с context ΠΈ Π²Ρ‹Π±ΠΎΡ€ΠΎΠΌ select Π² Golang.

Π”Π°Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ дСмонстрируСт использованиС контСкста (context.Context) для управлСния Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ Π³ΠΎΡ€ΡƒΠ½Ρ‚ΠΈΠ½, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ конструкции select для отслСТивания ΠΎΡ‚ΠΌΠ΅Π½Ρ‹ контСкста. Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ создаётся контСкст с Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚ΠΎΠΌ для остановки выполнСния ΠΏΠΎ истСчСнии Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, ΠΈ показываСтся ΠΊΠ°ΠΊ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ cancel.

package main
 
import (
	"context"
	"time"
 
	"github.com/juju/zaputil/zapctx"
	"go.uber.org/zap"
)
 
type key struct{}
 
func doWork(ctx context.Context) {
	logger := zapctx.Logger(ctx)
 
	logger.Info(ctx.Value(key{}).(string))
	for {
		select {
		case <-ctx.Done():
			logger.Info("ctx canceled")
			return
		default:
			logger.Info("Working")
			time.Sleep(time.Second)
		}
	}
}
 
func main() {
	ctx := context.Background()
 
	logger, _ := zap.NewProduction()
	logger = logger.With(zap.String("env", "prod"))
 
	logger.Info("Start app")
 
	logCtx := zapctx.WithLogger(ctx, logger)
	ctxLogWithValue := context.WithValue(logCtx, key{}, "iddqd")
 
	ctxTimeout, _ := context.WithTimeout(ctxLogWithValue, time.Second*5)
	doWork(ctxTimeout)
 
	ctxCancel, cancel := context.WithCancel(ctxLogWithValue)
	go doWork(ctxCancel)
	time.Sleep(time.Second * 6)
	cancel()
}