Menu
CoddyTech

Pernyataan select

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 62 dari 107.

Pernyataan select memungkinkan goroutine menunggu beberapa operasi channel secara bersamaan. Pernyataan ini mirip dengan pernyataan switch, tetapi setiap kasus melibatkan pengiriman atau penerimaan melalui channel. Saat beberapa channel siap, select memilih salah satunya secara acak.

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)
    
    go func() { ch1 <- "from channel 1" }()
    go func() { ch2 <- "from channel 2" }()
    
    select {
    case msg1 := <-ch1:
        fmt.Println(msg1)
    case msg2 := <-ch2:
        fmt.Println(msg2)
    }
}

Tanpa select, menerima dari ch1 akan memblokir hingga data tiba, sehingga data di ch2 mungkin terlewat. Dengan select, channel mana pun yang menerima data lebih dulu akan ditangani.

Case default membuat select tidak memblokir. Case ini langsung dijalankan jika tidak ada channel yang siap:

select {
case msg := <-messages:
    fmt.Println("Received:", msg)
default:
    fmt.Println("No message available")
}

Pola umum menggabungkan select dengan batas waktu menggunakan time.After, yang mengembalikan channel yang menerima nilai setelah durasi yang ditentukan:

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

Ini mencegah programmu menunggu selamanya saat operasi channel mungkin tidak pernah selesai.

challenge icon

Tantangan

Mudah

Mari buat monitor layanan yang menggunakan pernyataan select untuk menangani beberapa sumber data konkuren. Monitor kamu akan mendengarkan berbagai channel layanan secara bersamaan dan merespons dengan tepat saat data tiba atau saat tidak ada pembaruan.

Kamu akan mengatur kodemu dalam dua file:

  • monitor.go: Definisikan logika pemantauan layanan dengan penanganan channel berbasis select.

    Buat struct ServiceUpdate dengan field Name (string) dan Status (string).

    Implementasikan fungsi Monitor yang menerima tiga channel: primary chan ServiceUpdate, backup chan ServiceUpdate, dan done chan bool. Fungsi ini harus menggunakan select untuk mendengarkan ketiga channel secara bersamaan:

    • Saat menerima dari primary: kembalikan string berformat Primary: [Name] is [Status]
    • Saat menerima dari backup: kembalikan string berformat Backup: [Name] is [Status]
    • Saat menerima dari done: kembalikan Monitoring stopped

    Implementasikan fungsi CheckStatus yang menerima satu updates chan ServiceUpdate dan menggunakan select dengan kasus default untuk melakukan pemeriksaan non-blocking:

    • Jika ada pembaruan: kembalikan Update available: [Name]
    • Jika tidak ada pembaruan (kasus default): kembalikan No updates pending
  • main.go: Siapkan channel dan tunjukkan perilaku select blocking dan non-blocking.

    Baca mode dari input untuk menentukan skenario yang dijalankan: primary, backup, stop, atau check.

    Untuk mode primary, backup, dan stop: baca juga nama dan status layanan. Buat tiga channel, jalankan goroutine yang mengirim data ke channel yang sesuai berdasarkan mode, lalu panggil Monitor dan cetak hasilnya.

    Untuk mode check: baca nama dan status layanan, serta flag (send atau nosend) yang menunjukkan apakah data dikirim sebelum pemeriksaan. Buat channel buffered dengan kapasitas 1. Jika flag-nya send, kirim pembaruan ke channel sebelum memanggil CheckStatus. Cetak hasil CheckStatus.

Input berikut akan diberikan:

  • Baris 1: Mode (primary, backup, stop, atau check)
  • Baris 2: Nama layanan
  • Baris 3: Status layanan
  • Baris 4 (hanya untuk mode check): send atau nosend

Sebagai contoh, jika diberikan:

primary
Database
healthy

Output kamu seharusnya:

Primary: Database is healthy

Dan jika diberikan:

check
Cache
active
nosend

Output kamu seharusnya:

No updates pending

Coba sendiri

package main

import (
	"fmt"
)

func main() {
	var mode string
	fmt.Scanln(&mode)

	var serviceName string
	fmt.Scanln(&serviceName)

	var serviceStatus string
	fmt.Scanln(&serviceStatus)

	// TODO: Tangani berbagai mode: "primary", "backup", "stop", "check"
	
	// Untuk mode "primary", "backup", "stop":
	// - Buat tiga channel: primary, backup, done
	// - Jalankan goroutine yang mengirim data ke channel yang sesuai
	// - Panggil Monitor dan cetak hasilnya
	
	// Untuk mode "check":
	// - Baca flag tambahan ("send" atau "nosend")
	// - Buat channel dengan buffer berkapasitas 1
	// - Jika flag bernilai "send", kirim pembaruan ke channel
	// - Panggil CheckStatus dan cetak hasilnya
	
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Go online