/
genericevents.go
94 lines (83 loc) · 1.8 KB
/
genericevents.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package events
import (
"sync"
"github.com/teleclimber/DropServer/cmd/ds-host/domain"
)
type SubscribeIDs interface {
domain.UserID | domain.AppID | domain.AppspaceID
}
type DataTypes interface {
domain.AppURLData | domain.AppspaceID
}
type eventIDSubs[T SubscribeIDs, D DataTypes] struct {
subsMux sync.Mutex
subscribers map[T]*eventSubs[D]
}
func (s *eventIDSubs[T, D]) subscribe(subID T) <-chan D {
s.subsMux.Lock()
defer s.subsMux.Unlock()
if s.subscribers == nil {
s.subscribers = make(map[T]*eventSubs[D])
}
var es *eventSubs[D]
es = s.subscribers[subID]
if es == nil {
es = &eventSubs[D]{}
s.subscribers[subID] = es
}
return es.subscribe()
}
func (s *eventIDSubs[T, D]) unsubscribe(ch <-chan D) {
s.subsMux.Lock()
defer s.subsMux.Unlock()
if s.subscribers == nil {
return
}
for _, subs := range s.subscribers {
subs.unsubscribe(ch)
}
}
func (s *eventIDSubs[T, D]) send(subID T, data D) {
s.subsMux.Lock()
defer s.subsMux.Unlock()
subs := s.subscribers[subID]
if subs != nil {
subs.send(data)
}
}
type eventSubs[D DataTypes] struct {
subsMux sync.Mutex
subscribers []chan D
}
func (s *eventSubs[D]) subscribe() <-chan D {
s.subsMux.Lock()
defer s.subsMux.Unlock()
ch := make(chan D)
if s.subscribers == nil {
s.subscribers = make([]chan D, 0, 10)
}
s.subscribers = append(s.subscribers, ch)
return ch
}
func (s *eventSubs[D]) unsubscribe(ch <-chan D) {
s.subsMux.Lock()
defer s.subsMux.Unlock()
if s.subscribers == nil {
return
}
for i, c := range s.subscribers {
if c == ch {
s.subscribers[i] = s.subscribers[len(s.subscribers)-1]
s.subscribers = s.subscribers[:len(s.subscribers)-1]
close(c)
return
}
}
}
func (s *eventSubs[D]) send(data D) {
s.subsMux.Lock()
defer s.subsMux.Unlock()
for _, ch := range s.subscribers {
ch <- data
}
}