Skip to content

Instantly share code, notes, and snippets.

@Rubentxu
Last active August 29, 2015 14:27
Show Gist options
  • Save Rubentxu/911dddf93ece2d3f48f5 to your computer and use it in GitHub Desktop.
Save Rubentxu/911dddf93ece2d3f48f5 to your computer and use it in GitHub Desktop.
Broadcasting values in Go with linked channels
package main
import (
"fmt";
"time";
)
type broadcast struct {
c chan broadcast;
v interface{};
}
type Broadcaster struct {
// private fields:
ListenInt chan chan (chan broadcast);
ListenString chan chan (chan broadcast);
Sendc chan<- interface{};
}
// create a new broadcaster object.
func NewBroadcaster() Broadcaster {
listenInt := make(chan (chan (chan broadcast)));
listenString := make(chan (chan (chan broadcast)));
sendc := make(chan interface{});
go func() {
currc := make(chan broadcast, 1);
for {
select {
case v := <-sendc:
c := make(chan broadcast, 1);
b := broadcast{c: c, v: v};
currc <- b;
currc = c;
case r := <-listenInt:
r <- currc
case r := <-listenString:
r <- currc
}
}
}();
return Broadcaster{
ListenInt: listenInt,
ListenString: listenString,
Sendc: sendc,
};
}
// start listening to the broadcasts.
func (b Broadcaster) Listen(tipo int) {
c := make(chan chan broadcast, 0);
if tipo == 1 {
b.ListenInt <- c;
} else if tipo ==2 {
b.ListenString <- c
}
rv:= Receiver{<-c,tipo};
go rv.listen()
}
// broadcast a value to all listeners.
func (b Broadcaster) Write(v interface{}) { b.Sendc <- v }
type Receiver struct {
C chan broadcast;
Tipo int
}
func (r *Receiver) Read() interface{} {
b := <-r.C;
v := b.v;
r.C <- b;
r.C = b.c;
return v;
}
func (r *Receiver) listen() {
for v := r.Read(); v != nil; v = r.Read() {
if r.Tipo == 1 {
fmt.Println(v);
} else {fmt.Sprintf("Tipo excluido %d",r.Tipo)}
}
}
func main() {
var b = NewBroadcaster();
b.Listen(1);
b.Listen(2);
b.Listen(2);
for i := 0; i < 10; i++ {
b.Write(fmt.Sprintf("Valor %d",i));
}
b.Write(nil);
time.Sleep(3 * 1e9);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment