Dalam upaya mempelajari golang, saya mencari melalui sumber go untuk reverseproxy:

https://golang.org/src/net/http/httputil/reverseproxy.go

Saya menemukan blok kode ini (terpotong):

...
    errc := make(chan error, 1)
    spc := switchProtocolCopier{user: conn, backend: backConn}
    go spc.copyToBackend(errc)
    go spc.copyFromBackend(errc)
    <-errc
    return
}

// switchProtocolCopier exists so goroutines proxying data back and
// forth have nice names in stacks.
type switchProtocolCopier struct {
    user, backend io.ReadWriter
}


func (c switchProtocolCopier) copyFromBackend(errc chan<- error) {
    _, err := io.Copy(c.user, c.backend)
    errc <- err
}

func (c switchProtocolCopier) copyToBackend(errc chan<- error) {
    _, err := io.Copy(c.backend, c.user)
    errc <- err
}

Bagian yang menarik perhatian saya adalah pembuatan saluran buffer errc. Saya pikir (mungkin secara naif) bahwa kami akan menggunakan saluran yang tidak disangga dan yang kemudian menerima dari errc perlu dijalankan dua kali, seperti ini:

<-errc
<-errc

Seperti yang tertulis, saya mengerti bahwa membaca dari saluran akan memastikan setidaknya satu dari metode penyalinan telah berjalan. Saya juga mengerti bahwa pengiriman pertama ke saluran tidak akan memblokir, sedangkan yang kedua akan memblokir hanya jika yang pertama belum diterima.

Yang saya tidak mengerti, kenapa ditulis seperti ini. Apakah untuk memastikan bahwa hanya satu metode yang selesai? Jika itu masalahnya, tidak bisakah mereka berdua secara teknis berjalan?

Terima kasih!

go
0
wpanther 18 Juni 2020, 02:21

2 jawaban

Jawaban Terbaik

Saluran ukuran satu membantu mewujudkan semaphore biner.

Karena paling banyak satu nilai dikonsumsi dari saluran (on line 549), mengubah ukuran saluran menjadi lebih besar dari satu tidak akan memengaruhi perilaku yang ditampilkan saat ini, yang menunggu hingga setidaknya salah satu dari dua rutinitas selesai menjalankan Copy operasi.

0
Venkatesh-Prasad Ranganath 18 Juni 2020, 00:17

Tujuan dari kode ini adalah untuk menutup dua koneksi setelah io.Copy kembali di salah satu goroutine.

Kode terpotong menunda panggilan untuk menutup dua koneksi. Panggilan yang ditangguhkan dieksekusi setelah nilai diterima dari salah satu goroutine.

Operasi io.Copy di goroutine lain akan keluar dengan kesalahan saat koneksi ditutup. Goroutine itu dapat mengirim ke errc dan keluar karena saluran memiliki kapasitas satu.

Kedua goroutine selesai.

0
Muffin Top 18 Juni 2020, 00:32