agent
agent copied to clipboard
Channels don't behave like go's channels
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.
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.
Did the gem ever get updated?
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.
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
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. Aneachmethod 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)