Hi guys, I have a great demonstration on why an un-cached channel might 
malfunction while receiving:

package main
import(
    "fmt"
    "time"
    ) 

func main(){
    t := time.NewTicker(time.Second * 3)
    stopnow := make(chan bool) 
    //stopnow := make(chan bool, 1) //cached channel instead
    var n int

    for{
        select{
        case <-t.C:
            n++
            fmt.Printf("%d\n", n)
            
            if n==3{
                stopnow <- true //The Only Sending!!!
                t.Stop()
            }
            
        case a:=<-stopnow: //The Only Receiving!!!
            if a{
                goto END
            }
        }
    }
    END:
    fmt.Println("out of select")
}

In the code above, you will never see the printout "out of select" , 
because the for-select receiver is not working while the code is run inside 
timer receiver in the line " stopnow <- true".

So an un-cached channel like " stopnow := make(chan bool)" will 
occasionally but inevitably miss receiving while the code is busy 
processing a competing receiving.

That is why I use cached channel instead, like " stopnow := make(chan bool, 
1)", which un-received message(s) will be cached until gotten received.

However there comes another vulnerability - How large should the cache be?

In a simple scenario like this, I am very confident there will be 1 message 
to receive only. But on a complex server, it is very common that a 
goroutine will receive unexpected many messages from other goroutine or 
functions. And it is not safe for the programmer to just guess a ceiling 
for the number of unprocessed messages on any time - just as to guess the 
maximum on how many cars can line up after a red light. If you guess wrong, 
only one additional message will breach the cache and cause a crash:

package main

var c = make(chan int, 1)

func main() {
    
    c <- 1
    c <- 2 //fatal error: all goroutines are asleep - deadlock!
    c <- 3

} 

The code above crashes at the point that the cache of channel c is full, 
but the sender still puts another message into it.

What is your thought on this?
Regards,
    Zhaoxun

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/fefc350d-3423-4fb6-b844-703ce03c7e5fn%40googlegroups.com.

Reply via email to