FAQ
I saw a one-off panic in my app which raised some questions about
multi channel select statements. All the code for the project is on
github, and here's the stack trace:
https://gist.github.com/daaku/d50f927b89cc4eaa4d9d

--

Consider two channels:

allClosed
counter

The allClosed channel indicates the "work" should be considered done
and is used to indicate this to some worker goroutine so that it
exits. No code tries to send to allClosed, it is only ever closed.

--

The worker goroutine (1) has a select statement as such:

     select {
     case <-l.allClosed:
       return nil, ErrAlreadyClosed
     case l.counter <- inc:
       // do work
     }

--

Another goroutine (2) triggers a close as such:

       close(l.allClosed)
       close(l.counter)

--

It seems goroutine (1) ends up hitting the select and finds that
allClosed isn't closed but counter is closed and panics with a "send
on closed channel".

It seems like it's possible for the two close statements to execute
between the time the select tries the first case and the second case.
My question is that is this expected and if so how does one deal with
it?

--

I'm running this with tip from earlier today:
go version devel +bbe324079abe Tue May 07 11:41:36 2013 -0700 linux/amd64
Linux daaku.org 3.8.4-x86_64-linode31 #1 SMP Mon Mar 25 16:00:34 EDT
2013 x86_64 GNU/Linux


(Note: I *think* there may be a possible leak or missing timeout for
the stathat logic based on the number of other running goroutines that
I'm also looking into, but doesn't look related to this panic.)



Thanks,

-Naitik

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Jesse McNelis at May 8, 2013 at 5:57 am

    On Wed, May 8, 2013 at 3:27 PM, Naitik Shah wrote:
    It seems like it's possible for the two close statements to execute
    between the time the select tries the first case and the second case.
    My question is that is this expected and if so how does one deal with
    it?
    Yes it's expected. You deal with it by not closing a channel that still has
    senders wanting to send.
    Close() is a send operation, it sends a message to all receivers informing
    them not to expect any
    more messages, if there are still messages to be sent then this is a lie.

    If you want to signal a group of senders that they should stop sending then
    you still have to receive any values
    being sent between when the signal was sent and when it's finally acted
    upon by the senders. The senders also need to be charge of closing the
    channel.
    If you have multiple senders then they need to agree as to when no more
    values will be sent.
    Waitgroups are good for handling this. Put all the goroutines in a
    waitgroup, and have one waiting to close the channel when all the others
    have exited.
    Worker gorotines:
    select {
         case _, ok := <-l.allClosed:
           if !ok {
              wg.Done()
              return
           }
         case l.counter <- inc:
           // do work
    }

    Monitor goroutine:
    wg.Wait()
    close(counter)

    Some Goroutine triggering a close:
    close(allClosed) //signal all the senders to stop sending
    for i := range counter{} //drain the channel until it's closed.

    --
    =====================
    http://jessta.id.au

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedMay 8, '13 at 5:27a
activeMay 8, '13 at 5:57a
posts2
users2
websitegolang.org

2 users in discussion

Naitik Shah: 1 post Jesse McNelis: 1 post

People

Translate

site design / logo © 2021 Grokbase