To clarify the semantics aspects:

If A cannot proceed until B performs it’s work, because there is a dependency, 
then using a unbuffered channel simplifies a lot - you will always be at most 
“one event ahead” without any extra synchronization (wait groups, etc.)

> On Dec 18, 2018, at 2:01 PM, robert engels <reng...@ix.netcom.com> wrote:
> 
> Whether to use buffered or unbuffered comes down to two things:
> 
> 1) the semantics of the communication. because using unbuffered channels 
> simplifies a lot - knowing the send will not complete until the read 
> completes - it provides a synchronization mechanism between events/messages 
> and routines.
> 
> 2) performance… imagine the following pseudo code:
> 
> routine A sends messages to routine B
> routine B's processing of messages is variable - sometimes very fast, 
> sometimes very slow…
>     --- for example, let B be a logger, that every once in a while needs to 
> write to disk (the much slower operation)
> 
> so if A is a low latency event processor - getting stuck trying to send to B 
> would not be ideal - but since this only happens ‘rarely’ by using a buffered 
> channel (with the size = number of events expected in a B “slow” time), you 
> avoid “blocking” A
> 
> for example, A is sending financial orders to an exchange - you would not 
> want to every slow A down just because the logger was slow
> 
> For the performance aspect, you are essentially increasing the parallelism, 
> since any “block/wait” degrades this
> 
> Hope that helps.
> 
> 
> 
>> On Dec 18, 2018, at 1:49 PM, Chris Burkert <burkert.ch...@gmail.com 
>> <mailto:burkert.ch...@gmail.com>> wrote:
>> 
>> Robert,
>> it seems to me that you have a clear understanding about unbuffered vs. 
>> buffered channels. I feel unbuffered channels are safer to use especially in 
>> an acyclic directed graph of flowing values. Buffered channels seem to 
>> reduce blocking but I feel they come with the cost of such side effects like 
>> my initial problem of forgotten results in their channels. I would love to 
>> hear/read/see more on the unbuffered vs. buffered tradeoff to get rid of 
>> this gut feeling I am currently based on :-). Any good article you can point 
>> me to?
>> Thanks
>> 
>> Robert Engels <reng...@ix.netcom.com <mailto:reng...@ix.netcom.com>> schrieb 
>> am Di. 18. Dez. 2018 um 17:03:
>> That code is incorrect as well when using buffered channels. 
>> 
>> On Dec 18, 2018, at 10:00 AM, Skip Tavakkolian <skip.tavakkol...@gmail.com 
>> <mailto:skip.tavakkol...@gmail.com>> wrote:
>> 
>>> why not just  drop the select? i think the following is guaranteed because 
>>> putting things on rc has to succeed before putting true into dc:
>>> 
>>> package main
>>> 
>>> import (
>>>     "fmt"
>>> )
>>> 
>>> func do(i int, rc chan<- int, dc chan<- bool) {
>>>     rc <- i
>>>     dc <- true
>>> }
>>> 
>>> func main() {
>>>     worker := 10
>>>     rc := make(chan int, worker)
>>>     done := 0
>>>     dc := make(chan bool, worker)
>>>     for i := 0; i < worker; i++ {
>>>             go do(i, rc, dc)
>>>     }
>>>     for done < worker {
>>>             r := <-rc
>>>             fmt.Println(r)
>>>             <-dc
>>>             done++
>>>     }
>>> }
>>> 
>>> 
>>> On Tue, Dec 18, 2018 at 5:35 AM Chris Burkert <burkert.ch...@gmail.com 
>>> <mailto:burkert.ch...@gmail.com>> wrote:
>>> Dear all,
>>> 
>>> I have a couple of goroutines sending multiple results over a channel - a 
>>> simple fan-in. They signal the completion on a done channel. Main selects 
>>> on the results and done channel in parallel. As the select is random main 
>>> sometimes misses to select the last result. What would be the idiomatic way 
>>> to prevent this and completely drain the result channel?
>>> 
>>> Here is a minmal example which sometimes prints one 0 but should always 
>>> print two of them:
>>> 
>>> package main
>>> 
>>> import (
>>>         "fmt"
>>> )
>>> 
>>> func do(rc chan<- int, dc chan<- bool) {
>>>         rc <- 0
>>>         dc <- true
>>> }
>>> 
>>> func main() {
>>>         worker := 2
>>>         rc := make(chan int, worker)
>>>         done := 0
>>>         dc := make(chan bool, worker)
>>>         for i := 0; i < worker; i++ {
>>>                 go do(rc, dc)
>>>         }
>>>         for done < worker {
>>>                 select {
>>>                 case <-dc:
>>>                         done++
>>>                 case r := <-rc:
>>>                         fmt.Println(r)
>>>                 }
>>>         }
>>> }
>>> 
>>> many thanks
>>> Chris
>>> 
>>> -- 
>>> 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 
>>> <mailto:golang-nuts+unsubscr...@googlegroups.com>.
>>> For more options, visit https://groups.google.com/d/optout 
>>> <https://groups.google.com/d/optout>.
>>> 
>>> -- 
>>> 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 
>>> <mailto:golang-nuts+unsubscr...@googlegroups.com>.
>>> For more options, visit https://groups.google.com/d/optout 
>>> <https://groups.google.com/d/optout>.
> 

-- 
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to