Skip to content

Instantly share code, notes, and snippets.

@DAddYE
Created September 13, 2014 08:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DAddYE/73788610cc3e0d7ca872 to your computer and use it in GitHub Desktop.
Save DAddYE/73788610cc3e0d7ca872 to your computer and use it in GitHub Desktop.
Infinitely Buffered Channel
/*
This is an infinitely buffered channel.
*/
package main
import (
"fmt"
"sync"
"time"
)
type Channel struct {
In chan interface{}
Out chan interface{}
buffer []interface{}
}
func NewChannel() *Channel {
ch := new(Channel)
ch.In = make(chan interface{}, 0)
ch.Out = make(chan interface{}, 0)
ch.buffer = make([]interface{}, 0)
go ch.buffering()
return ch
}
func (ch *Channel) buffering() {
for {
if len(ch.buffer) > 0 {
select {
case in, open := <-ch.In:
if !open {
ch.drain()
return
}
ch.buffer = append(ch.buffer, in)
case ch.Out <- ch.buffer[0]:
ch.buffer = ch.buffer[1:]
}
} else {
in, open := <-ch.In
if !open {
ch.drain()
return
}
ch.buffer = append(ch.buffer, in)
}
}
}
func (ch *Channel) drain() {
for i := 0; i < len(ch.buffer); i++ {
ch.Out <- ch.buffer[i]
}
ch.buffer = ch.buffer[:]
close(ch.Out)
}
func main() {
ch := NewChannel()
ch.In <- "Hello"
ch.In <- "World"
ch.In <- "Fantastic"
// simulate worker
wg := new(sync.WaitGroup)
wg.Add(1)
go func() {
defer wg.Done()
for n := range ch.Out {
fmt.Println(n)
}
}()
time.Sleep(1 * time.Second)
ch.In <- 1
ch.In <- 2
ch.In <- 3
close(ch.In)
wg.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment