-
Notifications
You must be signed in to change notification settings - Fork 1
/
RingBuffer.go
62 lines (52 loc) · 1.29 KB
/
RingBuffer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// RingBuffer
package main
import (
"fmt"
)
/*
Connect two buffered channels through one goroutine
that forwards messages from the incoming channel
to the outgoing channel.
Whenever a new message can not be placed
on the outgoing channel,
take one message out of the outgoing channel
(that is the oldest message in the buffer),
drop it, and place the new message
in the newly freed up outgoing channel.
Plugging in this “channel struct” will never block
and will simply behave like a ring buffer.
That is, slower consumers might loose (their oldest)
messages, but will never be able to
block the main message processing loop.
*/
type RingBuffer struct {
inputChannel <-chan int
outputChannel chan int
}
func NewRingBuffer(inputChannel <-chan int, outputChannel chan int) *RingBuffer {
return &RingBuffer{inputChannel, outputChannel}
}
func (r *RingBuffer) Run() {
for v := range r.inputChannel {
select {
case r.outputChannel <- v:
default:
<-r.outputChannel
r.outputChannel <- v
}
}
close(r.outputChannel)
}
func main() {
in := make(chan int)
out := make(chan int, 6)
rb := NewRingBuffer(in, out)
go rb.Run()
for i := 0; i < 10; i++ {
in <- i
}
close(in)
for res := range out {
fmt.Println(res)
}
}