Buffered Channel

Pada sesi ini akan di bahas penggunaan Buffered Channel pada Go

Ketika terjadi proses kirim data via channel dari sebuah goroutine, maka harus ada goroutine lain yang bertugas menerima data dari channel yang sama, dengan proses serah-terima yang bersifat blocking.

Pada Buffered Channel, ditentukan angka jumlah buffer-nya. Angka tersebut menjadi penentu jumlah data yang bisa dikirimkan bersamaan. Selama jumlah data yang dikirim tidak melebihi jumlah buffer, maka pengiriman akan berjalan asynchronous (tidak blocking).

Ketika jumlah data yang dikirim sudah melewati batas buffer, maka pengiriman data hanya bisa dilakukan ketika salah satu data yang sudah terkirim adalah sudah diambil dari channel di goroutine penerima, sehingga ada slot channel yang kosong.

Untuk membuat Buffer kita cukup menambahkan argumen ke-2 pada inisialisasi Channel:

ch := make(chan int, 5)

Pada kode di atas argumen ke-2 menunjukan slot maksimal dari suatu Channel.

package main

import "fmt"

func main() {
	ch := make(chan int, 5)

	ch <- 1
	ch <- 10
	ch <- 9
	ch <- 8
	ch <- 4

	fmt.Println(<-ch)
	fmt.Println(<-ch)
	fmt.Println(<-ch)
	fmt.Println(<-ch)
	fmt.Println(<-ch)
}

Program di atas berjalan dengan sesuai karena kita mengirim data melalui channel sesuai dengan slot ytang tersedia yaitu sebanyak 5 slot.

Apa yang terjadi jika kita menambahkan dan mengirimkan 1 data lagi?

package main

import "fmt"

func main() {
	ch := make(chan int, 5)

	ch <- 1
	ch <- 10
	ch <- 9
	ch <- 8
	ch <- 4
	ch <- 20

	fmt.Println(<-ch)
	fmt.Println(<-ch)
	fmt.Println(<-ch)
	fmt.Println(<-ch)
	fmt.Println(<-ch)
	fmt.Println(<-ch)
}

Kita bisa lihat output program di atas, jika data yang kita kirim melalui channel melebihi kapasitas Buffer yang tersedia, maka program akan deadlock sebelum data diterima melalui channel.

Studi Kasus #2

Kita akan membuat program sederhana yang memperlihatkan penggunaan Buffer:

package main

import (
	"fmt"
	"time"
)

func write(ch chan int) {
	for i := 0; i < 5; i++ {
		ch <- i
		fmt.Println("successfully wrote", i, "to ch")
	}
	close(ch)
}
func main() {
	ch := make(chan int, 2)
	go write(ch)
	time.Sleep(2 * time.Second)
	for v := range ch {
		fmt.Println("read value", v, "from ch")
		time.Sleep(2 * time.Second)
	}
}

Pada kode di atas kita memiliki fungsi write untuk mengirim data melalui Channel. Lalu pada fungsi main kita menerima data melalui Channel.

Saat inisialisasi tipe data channel , kita membuat buffer sebanyak 2 slot. Maka proses asynchronous akan terhenti saat pengiriman data melalui channel sudah memenuhi slot tersebut dan akan dilanjutkan setelah data tersebut diterima melalui channel.

Buffer juga biasanya digunakan untuk proses antrian (queue)

Last updated