-
Notifications
You must be signed in to change notification settings - Fork 1
/
notifier.go
56 lines (48 loc) · 1.02 KB
/
notifier.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package main
import "container/list"
// notifierBufSize specifies how many messages to buffer.
// The channel is closed once the buffer
const notifierBufSize = 10
type Notifier struct {
st chan notifierState
}
type notifierState struct {
wait *list.List // of chan<- interface{}
}
func NewNotifier() *Notifier {
n := &Notifier{st: make(chan notifierState, 1)}
n.st <- notifierState{wait: list.New()}
return n
}
func (n *Notifier) Register() <-chan interface{} {
c := make(chan interface{}, notifierBufSize)
st := <-n.st
st.wait.PushBack(c)
n.st <- st
return c
}
func (n *Notifier) Unregister(c <-chan interface{}) {
st := <-n.st
for e := st.wait.Front(); e != nil; e = e.Next() {
if e.Value == c {
st.wait.Remove(e)
break
}
}
n.st <- st
}
func (n *Notifier) Notify(event interface{}) {
st := <-n.st
for e := st.wait.Front(); e != nil; e = e.Next() {
c := e.Value.(chan interface{})
select {
case c <- event:
// ok
default:
// would block - remove
st.wait.Remove(e)
close(c)
}
}
n.st <- st
}