Skip to content

Instantly share code, notes, and snippets.

@samthor
Created January 28, 2013 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samthor/4655953 to your computer and use it in GitHub Desktop.
Save samthor/4655953 to your computer and use it in GitHub Desktop.
CastGroup, something that lets listeners subscribe to broadcast events. Built for the garage door; will be used to support hanging GETs on some event.
package main
import (
"log"
"time"
)
func main() {
c := NewCastGroup()
go func() {
log.Printf("golang 1")
log.Printf("1.1 go: %v", c.Wait())
log.Printf("1.2 go: %v", c.Wait())
}()
go func() {
log.Printf("golang 2")
log.Printf("2.1 go: %v", c.Wait())
}()
go func() {
log.Printf("golang 3")
log.Printf("3.1 go: %v", c.Wait())
log.Printf("3.2 go: %v", c.Wait())
log.Printf("3.3 go: %v", c.Wait())
log.Printf("3.4 go: %v", c.Wait())
log.Printf("3.5 go: %v", c.Wait())
log.Printf("3.6 go: %v", c.Wait())
}()
count := 0
for {
time.Sleep(1 * time.Second)
count++
log.Printf("done event %d", count)
c.Done(count)
}
}
type CastGroup struct {
result chan interface{}
ch chan *event
}
type event struct {
wait chan bool
result interface{}
}
// Done signals all holders of the current event that the event is done; providing the
// given value in the event.
func (c *CastGroup) Done(v interface{}) {
// the passed event is overloaded with the result of the previous event...
c.result <- v
}
// Wait blocks until the current event is done, providing its result.
func (c *CastGroup) Wait() interface{} {
current := <-c.ch
_, ok := <-current.wait
if ok {
panic("chan should only ever be closed")
}
return current.result
}
func NewCastGroup() *CastGroup {
c := &CastGroup{make(chan interface{}), make(chan *event)}
go func() {
var current *event
for {
select {
case result := <-c.result:
if current != nil {
current.result = result
close(current.wait)
} else if result != nil {
panic("first update must be nil")
}
current = &event{make(chan bool), nil}
case c.ch <- current:
// Wait() is being invoked; pass the current event.
}
}
}()
c.Done(nil)
return c
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment