-
Notifications
You must be signed in to change notification settings - Fork 178
/
notifier.go
47 lines (42 loc) · 1.9 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
package engine
// Notifier is a concurrency primitive for informing worker routines about the
// arrival of new work unit(s). Notifiers essentially behave like
// channels in that they can be passed by value and still allow concurrent
// updates of the same internal state.
type Notifier struct {
// Illustrative description of the Notifier:
// * When the gate is activated, it will let a _single_ person step through the gate.
// * When somebody steps through the gate, it deactivates (atomic operation) and
// prevents subsequent people from passing (until it is activated again).
// * The gate has a memory and remembers whether it is activated. I.e. the gate
// can be activated while no-one is waiting. When a person arrives later, they
// can pass through the gate.
// * Activating an already-activated gate is a no-op.
//
// Implementation:
// We implement the Notifier using a channel. Activating the gate corresponds to
// calling `Notify()` on the Notifier, which pushes an element to the channel.
// Passing through the gate corresponds to receiving from the `Channel()`.
// As we don't want the routine sending the notification to wait until a worker
// routine reads from the channel, we need a buffered channel with capacity 1.
notifier chan struct{} // buffered channel with capacity 1
}
// NewNotifier instantiates a Notifier. Notifiers essentially behave like
// channels in that they can be passed by value and still allow concurrent
// updates of the same internal state.
func NewNotifier() Notifier {
return Notifier{make(chan struct{}, 1)}
}
// Notify sends a notification
func (n Notifier) Notify() {
select {
// to prevent from getting blocked by dropping the notification if
// there is no handler subscribing the channel.
case n.notifier <- struct{}{}:
default:
}
}
// Channel returns a channel for receiving notifications
func (n Notifier) Channel() <-chan struct{} {
return n.notifier
}