Use a ring channel to avoid blocking write of events (#2082)

* Use a ring channel to avoid blocking write of events

* Add eapache/channels dependency
This commit is contained in:
Manuel Alejandro de Brito Fontes 2018-02-13 17:46:18 -08:00 committed by GitHub
parent 33475b7184
commit 9bcb5b08ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 2833 additions and 78 deletions

72
vendor/github.com/eapache/channels/infinite_channel.go generated vendored Normal file
View file

@ -0,0 +1,72 @@
package channels
import "github.com/eapache/queue"
// InfiniteChannel implements the Channel interface with an infinite buffer between the input and the output.
type InfiniteChannel struct {
input, output chan interface{}
length chan int
buffer *queue.Queue
}
func NewInfiniteChannel() *InfiniteChannel {
ch := &InfiniteChannel{
input: make(chan interface{}),
output: make(chan interface{}),
length: make(chan int),
buffer: queue.New(),
}
go ch.infiniteBuffer()
return ch
}
func (ch *InfiniteChannel) In() chan<- interface{} {
return ch.input
}
func (ch *InfiniteChannel) Out() <-chan interface{} {
return ch.output
}
func (ch *InfiniteChannel) Len() int {
return <-ch.length
}
func (ch *InfiniteChannel) Cap() BufferCap {
return Infinity
}
func (ch *InfiniteChannel) Close() {
close(ch.input)
}
func (ch *InfiniteChannel) infiniteBuffer() {
var input, output chan interface{}
var next interface{}
input = ch.input
for input != nil || output != nil {
select {
case elem, open := <-input:
if open {
ch.buffer.Add(elem)
} else {
input = nil
}
case output <- next:
ch.buffer.Remove()
case ch.length <- ch.buffer.Length():
}
if ch.buffer.Length() > 0 {
output = ch.output
next = ch.buffer.Peek()
} else {
output = nil
next = nil
}
}
close(ch.output)
close(ch.length)
}