Skip to content

Instantly share code, notes, and snippets.

@Bwooce
Created April 13, 2013 10:46
Show Gist options
  • Save Bwooce/5377920 to your computer and use it in GitHub Desktop.
Save Bwooce/5377920 to your computer and use it in GitHub Desktop.
Pub/Sub example from Kyle Lemons. For further study as it contains a few new channel actions that I don't yet get.
package main
import "fmt"
const Buffer = 3
type Value int
type Producer struct {
subs map[chan Value]bool
sub chan chan Value
unsub chan chan Value
}
func NewProducer() *Producer {
p := &Producer{
subs: make(map[chan Value]bool),
sub: make(chan chan Value),
unsub: make(chan chan Value),
}
values := make(chan Value)
go func() {
for i := Value(0); ; i++ {
values <- i
}
}()
go func() {
next := make(chan Value, Buffer)
for {
select {
case v := <-values:
for c := range p.subs {
select {
case c <- v:
default:
}
}
case p.sub <- next:
p.subs[next], next = true, make(chan Value, Buffer)
case c := <-p.unsub:
delete(p.subs, c)
}
}
}()
return p
}
func (p *Producer) Subscribe() chan Value {
return <-p.sub
}
func (p *Producer) Unsubscribe(ch chan Value) {
p.unsub <- ch
}
func main() {
p := NewProducer()
ch := p.Subscribe()
defer p.Unsubscribe(ch)
for i := 0; i < 10; i++ {
fmt.Println(i, <-ch)
}
}
@Bwooce
Copy link
Author

Bwooce commented Apr 13, 2013

Line 22-26 are just a dummy fill function for the channel, it blocks when it gets to 3 (Buffer) anyway.

Line 39 confused me, but the #go-nuts guys (Kyle included!) pointed out that it's p.subs[next] = true; next=make(..)

All good. I've learnt a lot from these 63 lines of code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment