agent icon indicating copy to clipboard operation
agent copied to clipboard

Channels don't behave like go's channels

Open corasaurus-hex opened this issue 11 years ago • 5 comments
trafficstars

Receiving on a closed channel in agent will raise an error. In go it will return immediately with the zero value for the object's type and false (in the case of a multi-value receive).

http://golang.org/ref/spec#Close

We should fix this, but it's a pretty major change and so we should at least bump a minor version.

corasaurus-hex avatar Jul 17 '14 18:07 corasaurus-hex

Looks like the code to fix this issue was merged. Would it be possible to get a new version released on rubygems?

I guess until then I'll just refer to commit 3e113ad2de87bf1d6c8fa99d10b4cd0ff5ca91ea in my Gemfile.

csaunders avatar Aug 12 '14 23:08 csaunders

Did the gem ever get updated?

Integralist avatar Dec 10 '14 12:12 Integralist

Looks like that still isn't the case as https://github.com/igrigorik/agent/blob/3e113ad2de87bf1d6c8fa99d10b4cd0ff5ca91ea/lib/agent/version.rb hasn't been updated since Feb 2013.

csaunders avatar Dec 10 '14 14:12 csaunders

I'm happy to push out a new release, but not sure if anything is blocking.. @nate any thoughts? In particular, it looks like jruby and rbx are having some issues with master: https://travis-ci.org/igrigorik/agent

igrigorik avatar Dec 10 '14 16:12 igrigorik

This is still not fully addressed. Channels that are closed should still allow receivers to receive the contents of the channel at the time the channel was closed.

package main

func main() {
    c := make(chan int, 3)
    c <- 1
    c <- 2
    close(c)

    i, ok := <-c
    println(i, ",", ok)
    i, ok = <-c
    println(i, ",", ok)
    i, ok = <-c
    println(i, ",", ok)
}

/* Output:
 *
 *  1 , true
 *  2 , true
 *  0 , false */
require "rubygems"
require "agent"

c = channel!(Integer, 3)
c << 1
c << 2
c.close

i, ok = c.receive
puts("#{i.inspect} , #{ok.inspect}")
i, ok = c.receive
puts("#{i.inspect} , #{ok.inspect}")
i, ok = c.receive
puts("#{i.inspect} , #{ok.inspect}")

# Output:
#   nil , false
#   nil , false
#   nil , false

I discovered this when trying to implement one of go's channel tests using agent.

There are a few other issues to address here as well.

  • receive cases in select statements should receive the error value as well so we can see that the channel is closed. checking for a nil value is not good enough.
  • We need something similar to go's for v := range myChannel. An each method would work well.
  • Think through and handle the implications of channels being marshaled to string and then the queue being closed. When a channel closes the queue gets removed from the global queue registry. When this marshaled channel is returned to an object it would not be able to find the queue and thus would not be able to perform the behavior at the beginning of this comment. This means we either need to disallow channel marshaling or come up with another way to track queues and queue references safely. (UGH)

corasaurus-hex avatar Mar 11 '15 20:03 corasaurus-hex