Repository navigation
Expand file tree
/
Copy pathobserver.go
More file actions
76 lines (62 loc) · 1.48 KB
/
Copy pathobserver.go
File metadata and controls
76 lines (62 loc) · 1.48 KB
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package chancon
import (
"github.com/google/uuid"
"github.com/labstack/gommon/log"
"sync"
)
type ObserverCallback func(m *Message) error
type Observer struct {
Id uuid.UUID
Channel string
Callback ObserverCallback
}
type observerManager struct {
channels map[string][]*Observer
lock *sync.RWMutex
}
func newObserverManager() *observerManager {
return &observerManager{
channels: map[string][]*Observer{},
lock: &sync.RWMutex{},
}
}
func (o *observerManager) On(channel string, callback ObserverCallback) func() {
o.lock.Lock()
defer o.lock.Unlock()
if o.channels[channel] == nil {
o.channels[channel] = []*Observer{}
}
observer := &Observer{
Id: uuid.New(),
Callback: callback,
Channel: channel,
}
o.channels[channel] = append(o.channels[channel], observer)
return func() {
o.lock.Lock()
defer o.lock.Unlock()
newObservers := []*Observer{}
for _, slicedObserver := range o.channels[channel] {
if observer.Id != slicedObserver.Id {
newObservers = append(newObservers, slicedObserver)
}
}
o.channels[channel] = newObservers
}
}
func (o *observerManager) handle(message *Message) {
o.lock.RLock()
defer o.lock.RUnlock()
observers, ok := o.channels[message.Channel.Name]
if !ok {
return
}
for _, observer := range observers {
go func(observer *Observer) {
err := observer.Callback(message)
if err != nil {
log.Errorf("Error in observer (channel %s): %s", message.Channel.Name, err.Error())
}
}(observer)
}
}