Kodeloka
  1. Kodeloka
  2. Kelas Golang
  3. Materi

Domain 7 · 5 bab

Package Context

110. Pengenalan Context & Context Tree

Arsitektur Parent-Child Context Tree dan sinyal cancellation.

Package Context

Membawa sinyal cancellation, deadline, dan request-scoped data. Jika Parent dibatalkan, seluruh Child otomatis terbatalkan secara berantai!

Contoh program

package main

import (
	"context"
	"fmt"
)

func main() {
	ctx := context.Background()
	fmt.Println("Root Context:", ctx)
}

Praktik dan kuis bab ini di kelas interaktif →

111. context.Background, context.TODO, & WithValue

Membuat Root Context dan menyisipkan metadata request-scoped.

WithValue

context.WithValue(parent, key, value) menyisipkan data. Membaca: ctx.Value(key).

Contoh program

package main

import (
	"context"
	"fmt"
)

func main() {
	parent := context.Background()
	ctx := context.WithValue(parent, "userID", "USER-123")
	fmt.Println("User ID:", ctx.Value("userID"))
}

Praktik dan kuis bab ini di kelas interaktif →

112. context.WithCancel (Sinyal Pembatalan Manual)

Mengirim sinyal cancel untuk menghentikan Goroutines.

WithCancel

ctx, cancel := context.WithCancel(parent). Saat cancel() dipanggil, ctx.Done() menutup channel dan memberikan sinyal.

Contoh program

package main

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

func Counter(ctx context.Context) <-chan int {
	ch := make(chan int)
	go func() {
		defer close(ch)
		n := 1
		for {
			select {
			case <-ctx.Done():
				fmt.Println("Counter dihentikan!")
				return
			case ch <- n:
				n++
			}
		}
	}()
	return ch
}

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	for n := range Counter(ctx) {
		fmt.Println("Angka:", n)
		if n == 3 {
			cancel()
			break
		}
	}
	time.Sleep(100 * time.Millisecond)
}

Praktik dan kuis bab ini di kelas interaktif →

113. context.WithTimeout & WithDeadline

Membatalkan proses otomatis jika melebihi batas waktu.

WithTimeout & WithDeadline

WithTimeout(parent, 5*time.Second) — durasi relatif. WithDeadline(parent, time.Time) — waktu spesifik. Selalu panggil defer cancel()!

Contoh program

package main

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

func SlowQuery(ctx context.Context) {
	select {
	case <-time.After(500 * time.Millisecond):
		fmt.Println("Query Selesai!")
	case <-ctx.Done():
		fmt.Println("TIMEOUT!", ctx.Err())
	}
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
	defer cancel()
	SlowQuery(ctx)
}

Praktik dan kuis bab ini di kelas interaktif →

114. Goroutine Leak Prevention & Best Practices

Mencegah Goroutine Leak dan konvensi penulisan parameter Context.

Goroutine Leak & Best Practices

Goroutine Leak = goroutine yang tak pernah mati karena ter-block channel. Solusi: selalu teruskan Context dan dengarkan <-ctx.Done().

Konvensi:

  • Parameter ctx context.Context selalu di posisi PERTAMA
  • Jangan simpan Context di struct
  • Selalu defer cancel()

Contoh program

package main

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

func SafeRoutine(ctx context.Context) {
	go func() {
		for {
			select {
			case <-ctx.Done():
				fmt.Println("Goroutine Berhasil Dihentikan!")
				return
			default:
				time.Sleep(10 * time.Millisecond)
			}
		}
	}()
}

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	SafeRoutine(ctx)
	fmt.Println("Goroutines aktif:", runtime.NumGoroutine())
	cancel()
	time.Sleep(50 * time.Millisecond)
	fmt.Println("Setelah cancel:", runtime.NumGoroutine())
}

Praktik dan kuis bab ini di kelas interaktif →