A more idiomatic way of trying a non-blocking send on a buffered channel

and falling back to a blocking send inside a goroutine.

This really needs to be fixed. The situation only arises when events are
sent and aren't pulled off the channel using {Wait,Poll}ForEvent.
Namely, if the event send blocks, the entire program will deadlock.

Using a goroutine is not ideal because we lose a guarantee of order:
that events are processed in the order of their arrival. However, it
seems OK as a temporary band-aide for a situation that probably doesn't
arise too often.

What I need to do is implement a dynamic queue. Here is a reference
implementation: http://play.golang.org/p/AiHBsxTFpj
This commit is contained in:
Andrew Gallant (Ocelot) 2012-05-12 21:55:57 -04:00
parent 7abc9c6455
commit 6bdfd1d1b1
1 changed files with 5 additions and 3 deletions

View File

@ -379,12 +379,14 @@ func (c *Conn) readResponses() {
// FIXME: I'm not sure if using a goroutine here to guarantee // FIXME: I'm not sure if using a goroutine here to guarantee
// a non-blocking send is the right way to go. I should implement // a non-blocking send is the right way to go. I should implement
// a proper dynamic queue. // a proper dynamic queue.
if cap(c.eventChan) == len(c.eventChan) { // I am pretty sure this also loses a guarantee of events being
// processed in order of being received.
select {
case c.eventChan <- event:
default:
go func() { go func() {
c.eventChan <- event c.eventChan <- event
}() }()
} else {
c.eventChan <- event
} }
// No more processing for events. // No more processing for events.