Select & Patterns — Go

Select Statement select memungkinkan goroutine menunggu di beberapa channel sekaligus. Mirip switch, tapi untuk channel operations. Sintaks Dasar select { case

Select Statement

select memungkinkan goroutine menunggu di beberapa channel sekaligus. Mirip switch, tapi untuk channel operations.

Sintaks Dasar

select {
case msg := <-ch1:
    fmt.Println("Dari ch1:", msg)
case msg := <-ch2:
    fmt.Println("Dari ch2:", msg)
case ch3 <- "hello":
    fmt.Println("Terkirim ke ch3")
default:
    fmt.Println("Tidak ada channel yang ready")
}

Timeout Pattern

select {
case result := <-ch:
    fmt.Println("Hasil:", result)
case <-time.After(3 * time.Second):
    fmt.Println("Timeout!")
}

Done Channel Pattern

Menggunakan channel untuk memberi sinyal berhenti ke goroutine:

func worker(done chan bool) {
    for {
        select {
        case <-done:
            fmt.Println("Worker berhenti")
            return
        default:
            fmt.Println("Bekerja...")
            time.Sleep(500 * time.Millisecond)
        }
    }
}

func main() {
    done := make(chan bool)
    go worker(done)
    time.Sleep(2 * time.Second)
    done <- true // Kirim sinyal berhenti
}

Context (Modern Approach)

Package context adalah cara modern untuk mengontrol goroutine:

import "context"

func worker(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("Worker dibatalkan:", ctx.Err())
            return
        default:
            fmt.Println("Bekerja...")
            time.Sleep(500 * time.Millisecond)
        }
    }
}

func main() {
    ctx, cancel := context.WithTimeout(
        context.Background(),
        2*time.Second,
    )
    defer cancel()

    go worker(ctx)
    time.Sleep(3 * time.Second)
}

Common Patterns

Worker Pool Example

func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        fmt.Printf("Worker %d memproses job %d\n", id, j)
        results <- j * 2
    }
}

func main() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)

    // Buat 3 worker
    for w := 1; w <= 3; w++ {
        go worker(w, jobs, results)
    }

    // Kirim 5 job
    for j := 1; j <= 5; j++ {
        jobs <- j
    }
    close(jobs)

    // Kumpulkan hasil
    for a := 1; a <= 5; a++ {
        fmt.Println(<-results)
    }
}

Yang akan kamu pelajari