-
Notifications
You must be signed in to change notification settings - Fork 0
/
topics.go
61 lines (48 loc) · 1.58 KB
/
topics.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
package main
import (
set "github.com/deckarep/golang-set"
)
// Topics manages the subscribed topics and calls subscribe and unsubscribe as neccessary
type Topics struct {
subscribedTopics set.Set
subscribe func(topic string)
unsubscribe func(topic string)
}
// NewTopics create new topics state with subscibe and unsubscribe handlers
func NewTopics(subscribe func(topic string), unsubscribe func(topic string)) *Topics {
return &Topics{
subscribe: subscribe,
unsubscribe: unsubscribe,
subscribedTopics: set.NewSet(),
}
}
// UpdateTopics set the internal state of subscribed topics
// and calls the subscribe handler on all new topics and unsubscribe on all obsolte topics.
func (t *Topics) UpdateTopics(topics []string) {
updatedTopics := setFromStringSlice(topics)
if !t.subscribedTopics.Equal(updatedTopics) {
newTopics := updatedTopics.Difference(t.subscribedTopics)
for _, topic := range stringSliceFromSet(newTopics) {
t.subscribe(topic)
}
obsoletTopics := t.subscribedTopics.Difference(updatedTopics)
for _, topic := range stringSliceFromSet(obsoletTopics) {
t.unsubscribe(topic)
}
}
t.subscribedTopics = updatedTopics
}
func setFromStringSlice(strings []string) set.Set {
stringsAsInterface := make([]interface{}, len(strings))
for i := range stringsAsInterface {
stringsAsInterface[i] = strings[i]
}
return set.NewSetFromSlice(stringsAsInterface)
}
func stringSliceFromSet(s set.Set) []string {
strings := make([]string, s.Cardinality())
for i, stringAsInterface := range s.ToSlice() {
strings[i] = stringAsInterface.(string)
}
return strings
}