Lompat ke konten Lompat ke sidebar Lompat ke footer

Golang Concurrency #4

 

📌 Studi Kasus: Proses Scraping Website Secara Paralel

Misalkan kita ingin melakukan web scraping ke beberapa URL sekaligus. Jika dilakukan secara berurutan (synchronous), maka akan sangat lambat karena harus menunggu setiap request selesai satu per satu.

Dengan goroutine, kita bisa menjalankan request secara paralel, sehingga proses scraping menjadi lebih cepat dan efisien.


📝 Implementasi Scraper dengan Goroutine dan WaitGroup

package main import ( "fmt" "net/http" "sync" "time" ) // fetchURL melakukan request ke URL dan mengembalikan status code func fetchURL(url string, wg *sync.WaitGroup, results chan<- string) { defer wg.Done() // Mengurangi counter WaitGroup setelah selesai start := time.Now() resp, err := http.Get(url) elapsed := time.Since(start) if err != nil { results <- fmt.Sprintf("Error fetching %s: %v", url, err) return } defer resp.Body.Close() results <- fmt.Sprintf("Fetched %s in %v (Status: %d)", url, elapsed, resp.StatusCode) } func main() { // Daftar URL yang akan di-scrape urls := []string{ "https://golang.org", "https://www.google.com", "https://www.github.com", "https://www.stackoverflow.com", "https://www.reddit.com", } var wg sync.WaitGroup results := make(chan string, len(urls)) // Channel untuk menyimpan hasil scraping // Memulai goroutine untuk setiap URL for _, url := range urls { wg.Add(1) // Menambah counter sebelum menjalankan goroutine go fetchURL(url, &wg, results) } // Menutup channel setelah semua goroutine selesai go func() { wg.Wait() close(results) }() // Menampilkan hasil for result := range results { fmt.Println(result) } }

📝 Penjelasan Kode:

  1. Membuat fungsi fetchURL()

    • Fungsi ini mengambil URL, mengirim request, dan mengembalikan hasilnya ke channel.
    • Menggunakan defer wg.Done() untuk memastikan bahwa counter WaitGroup berkurang setelah goroutine selesai.
  2. Menjalankan goroutine untuk setiap URL

    • Looping daftar URL dan menjalankan fetchURL(url) secara paralel dengan go fetchURL(url, &wg, results).
    • Sebelum menjalankan goroutine, kita menambah counter WaitGroup dengan wg.Add(1).
  3. Sinkronisasi dengan WaitGroup

    • Setelah semua goroutine berjalan, wg.Wait() digunakan untuk menunggu sampai semua goroutine selesai.
    • Kita menutup channel results setelah wg.Wait() selesai agar loop for result := range results tahu kapan harus berhenti membaca.
  4. Channel results untuk komunikasi antar goroutine

    • Setiap hasil scraping dikirim ke channel agar bisa dibaca oleh goroutine utama.

⏳ Perbandingan Waktu Eksekusi

MetodeWaktu Eksekusi
Tanpa Goroutine (Sequential)~5 detik (karena setiap request menunggu yang sebelumnya selesai)
Dengan Goroutine (Concurrent)~1-2 detik (karena request berjalan paralel)

🚀 Keuntungan Pendekatan Ini

Efisien dan Cepat – Request berjalan paralel, mempercepat proses scraping.
Tidak Perlu time.Sleep() – Menggunakan WaitGroup untuk sinkronisasi secara benar.
Aman dengan Channel – Menghindari kondisi race dengan mengirim hasil scraping ke channel.


🎯 Kesimpulan

Goroutine sangat efektif digunakan untuk kasus I/O-bound seperti web scraping, fetching data dari API, atau membaca banyak file secara bersamaan.
Jika ada pertanyaan atau ingin contoh lainnya, silakan tanya! 🚀