Created
April 13, 2013 10:46
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.