Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add select_ok function to detect closed channels during select #48

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Add select_ok function to detect closed channels during select #48

wants to merge 7 commits into from

Conversation

kkroening
Copy link
Contributor

@kkroening kkroening commented Jun 12, 2017

In Go, it's possible to detect closed channels inside a select. It doesn't appear that goless has any way to do this out-of-the-box, since the select function doesn't return an ok indication.

Here's an example:

for {
    select {
    case x, ok := <-ch1:
        fmt.Println("ch1", x, ok)
        if !ok {
            ch1 = nil
        }
    case x, ok := <-ch2:
        fmt.Println("ch2", x, ok)
        if !ok {
            ch2 = nil
        }
    }

    if ch1 == nil && ch2 == nil {
        break
    }
}

I added a select_ok function that behaves the same as select but handles closed channels correctly and returns an ok indication:

while True:
    cases = [goless.rcase(in1), goless.rcase(in2)]
    chosen, value, ok = goless.select_ok(cases)
    if chosen.chan is in1:
        print 'ch1', value, ok
        if !ok:
            in1 = None
    else:
        print 'ch2', value, ok
        if !ok:
            in2 = None
    if in1 is None and in2 is None:
        break

Closed channels cases take precedence over the default case. And if a normal select is performed on a closed channel, a ClosedChannel exception is raised, similar to how Go complains in the same case.

The changes to check for closed channels are a bit hacky: in selecting.py, it directly accesses the channels _closed property. I'm not sure of a better way to do this. I tried changing recv_ready/send_ready to return True if the channel is closed (which would cause the select to choose the corresponding case), but that broke a bunch of stuff. Would love to hear if there's a better way to do this.

@kkroening
Copy link
Contributor Author

Note: #49 fixes CI for this branch

@rgalanakis
Copy link
Owner

I need a bit more time to review this... will get back to you soon.

@coveralls
Copy link

coveralls commented Jun 19, 2017

Coverage Status

Coverage decreased (-0.4%) to 93.333% when pulling 9e6ac3d on kkroening:select-ok into 286cd69 on rgalanakis:master.

@coveralls
Copy link

coveralls commented Jun 19, 2017

Coverage Status

Coverage decreased (-0.4%) to 93.333% when pulling a3dfc5b on kkroening:select-ok into 286cd69 on rgalanakis:master.

@kkroening
Copy link
Contributor Author

Cool, no worries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants